هر پروژهی نرمافزاری سفارشی یک لحظهی تعیینکننده دارد، و آن لحظه معمولاً هفتهی دوم است — جایی که تصمیم میگیرید داده چطور ذخیره شود. اگر آن تصمیم درست باشد، شش ماه بعد افزودن یک قابلیت جدید یک روز کار است. اگر غلط باشد، همان قابلیت دو هفته طول میکشد و هر بار چیز دیگری را میشکند.
چرا مدل داده زودتر از رابط کاربری بسته میشود
وسوسهی طبیعی این است که از صفحهها شروع کنیم، چون صفحهها را میشود به مشتری نشان داد. ولی صفحه بازتاب داده است، نه برعکس. وقتی از رابط کاربری شروع میکنید، مدل داده را ناخودآگاه از روی همان صفحهها میسازید و موجودیتهایی که هیچ صفحهای ندارند — مثل «تاریخچهی تغییر قیمت» یا «وضعیت میانی سفارش» — اصلاً ساخته نمیشوند.
بعد که کسی میپرسد «قیمت این کالا سه ماه پیش چند بود؟»، جوابی وجود ندارد، چون آن داده هرگز ذخیره نشده است.
سه سوالی که قبل از اولین جدول میپرسیم
چه چیزی باید تاریخچه داشته باشد؟ هر چیزی که ممکن است کسی دربارهی گذشتهاش سوال کند، باید بهجای بازنویسی، نسخهگذاری شود. قیمت، وضعیت، مانده حساب، تخصیص. بازنویسی ارزان است تا روزی که نیست.
مرز ماژولها کجاست؟ انبار باید بتواند بدون دانستن اینکه «فروش» چیست کار کند. اگر نتواند، بعداً نمیشود فقط انبار را عوض کرد.
چه چیزی واقعاً یکتاست؟ کد کالا در سطح شرکت یکتاست یا در سطح شعبه؟ جواب این سوال یک ایندکس ساده است امروز، و یک مهاجرت دردناک سال بعد.
نمونه: چرا وضعیت را ستون نمیگذاریم
فرض کنید سفارش وضعیت دارد: ثبتشده، تأییدشده، ارسالشده، تحویلشده. سادهترین
کار یک ستون status است. اما تقریباً همیشه سوال بعدی این است: «کی تأیید شد؟
چه کسی تأیید کرد؟ بین تأیید و ارسال چقدر طول کشید؟»
# بهجای این
class Order(models.Model):
status = models.CharField(max_length=20)
# این
class OrderEvent(models.Model):
order = models.ForeignKey(Order, related_name="events")
status = models.CharField(max_length=20)
actor = models.ForeignKey(User, null=True)
at = models.DateTimeField(auto_now_add=True)
وضعیت فعلی میشود آخرین رویداد. هزینهاش یک جدول اضافه است؛ فایدهاش این است که هر سوالی دربارهی زمان و مسئولیت، جواب دارد.
جمعبندی
تغییر یک جدول در هفتهی دوم تقریباً رایگان است. همان تغییر در ماه ششم یعنی مهاجرت داده، بازنویسی گزارشها و ریسک. برای همین است که ما در نمو معماری داده را قبل از طراحی صفحه میبندیم — نه از سر وسواس، بلکه چون ارزانترین جای اصلاح همانجاست.