تمرینهای حلشدهی مدلسازی داده: رزرو هتل، فروشگاه، شرکت و شبکهی اجتماعی
بهترین راه یادگیری مدلسازی، حل تمرین است. این درس چهار سناریوی واقعی دارد؛ برای هر کدام اول خودت موجودیتها، ارتباطها، کاردینالیتی و کلیدها را روی کاغذ یا در طراح تعاملی ER بنویس، سپس پاسخ را باز کن و مقایسه کن.
روش حل هر تمرین
- اسمها را زیر خط بکش (موجودیتها و صفتها) و فعلها را (ارتباطها).
- برای هر ارتباط دو جمله بنویس و حداقل و حداکثر را مشخص کن.
- رابطههای چندبهچند را با جدول واسط بشکن و صفتهای رابطه را به همان جدول ببر.
- قواعد کسبوکار (یکتایی، بازهی مجاز، «حداکثر یکبار») را به قید تبدیل کن.
- مدل را با چکلیست بازبینی بسنج و در نهایت اسکریپت SQL بنویس.
تمرینها
چهار تمرین در بخش «تمرینهای خودآزمایی» پایین همین صفحه آمده است؛ هرکدام را باز کن، خودت حل کن و بعد پاسخ را ببین. پاسخ هر تمرین شامل تحلیل، نمودار منطقی و کد SQL است.
معیار موفقیت
| اگر توانستی... | یعنی |
|---|---|
| رابطهی چندبهچند را در ۵ ثانیه تشخیص بدهی و جدول واسطش را بنویسی | قواعد نگاشت ER به جدول را فهمیدهای |
| بگویی صفت یک رابطه (ساعت کار، قیمت واحد) در کدام جدول مینشیند | تفاوت صفت موجودیت و صفت رابطه را میدانی |
| قاعدههای کسبوکار را به قید SQL تبدیل کنی | از مرز تحلیل به پیادهسازی رسیدهای |
| از روی نمودار، کوئریهای معنادار بنویسی | مدلت واقعاً کاربردی است |
بعد از این تمرینها، آمادهای پروژهی دانشگاهی خودت را شروع کنی؛ راهنمای پروژهی درس پایگاهداده مسیر و ساختار گزارش را میدهد.
تمرینهای خودآزمایی
اول خودت جواب بده، بعد پاسخ را باز کن و مقایسه کن.
۱تمرین ۱ — رزرو هتل: هتلی مهمانها را با نام و تلفن ثبت میکند. هر اتاق شماره و قیمت هر شب دارد. مهمان میتواند چند رزرو در تاریخهای مختلف داشته باشد؛ هر رزرو یک اتاق و بازهی زمانی دارد و چند پرداخت (بیعانه، تسویه) میگیرد.نمایش پاسخ
موجودیتها: Guest، Room، Booking، Payment. «رزرو» رابطهی مهمان و اتاق در یک بازهی زمانی است، پس خودش موجودیت میشود.
ارتباطها: یک مهمان چند رزرو دارد (1:N)، یک اتاق در طول زمان در چند رزرو میآید (1:N) و یک رزرو میتواند چند پرداخت داشته باشد (1:N، مثلاً بیعانه و تسویه).
قیدهای مهم: تاریخ خروج باید بعد از ورود باشد، و یک اتاق در یک بازه دو رزرو همپوشان نداشته باشد (این قید با CHECK ساده بیان نمیشود و معمولاً با Trigger یا پرسوجوی بررسی پیش از درج اعمال میشود).
CREATE TABLE Booking ( BookingId INT IDENTITY PRIMARY KEY, GuestId INT NOT NULL REFERENCES Guest(GuestId), RoomId INT NOT NULL REFERENCES Room(RoomId), CheckIn DATE NOT NULL, CheckOut DATE NOT NULL, CONSTRAINT CK_Booking_Dates CHECK (CheckOut > CheckIn) ); -- بررسی همپوشانی پیش از ثبت رزرو جدید (@RoomId, @In, @Out) SELECT 1 FROM Booking WHERE RoomId = @RoomId AND @In < CheckOut AND @Out > CheckIn; -- اگر ردیفی آمد، اتاق مشغول است
مدل کامل: باز کردن در طراح تعاملی.
۲تمرین ۲ — فروشگاه اینترنتی: مشتریان سفارش میدهند؛ هر سفارش چند محصول با تعداد دارد. محصولها در دستهبندی هستند. فاکتورهای قدیمی نباید با تغییر قیمت محصول عوض شوند.نمایش پاسخ
نکتهی اصلی: بین «سفارش» و «محصول» رابطهی چندبهچند است. جدول واسط OrderItem علاوه بر تعداد، قیمت واحد در لحظهی خرید را هم نگه میدارد؛ چون قیمت محصول بعداً تغییر میکند ولی فاکتور قدیمی نباید عوض شود.
CREATE TABLE OrderItem ( OrderId INT NOT NULL REFERENCES Orders(OrderId), ProductId INT NOT NULL REFERENCES Product(ProductId), Quantity INT NOT NULL CHECK (Quantity > 0), UnitPrice DECIMAL(12,2) NOT NULL, PRIMARY KEY (OrderId, ProductId) ); -- جمع هر سفارش SELECT o.OrderId, SUM(i.Quantity * i.UnitPrice) AS Total FROM Orders o JOIN OrderItem i ON i.OrderId = o.OrderId GROUP BY o.OrderId;
نام جدول Orders عمداً جمع نوشته شده، چون Order کلمهی رزروشدهی SQL است. مدل کامل: طراح تعاملی.
۳تمرین ۳ — شرکت و پروژه: کارمندان در بخشها کار میکنند و هر کارمند یک مدیر (که او هم کارمند است) دارد. کارمندان در چند پروژه با ساعت کار مشخص مشارکت دارند.نمایش پاسخ
سه ارتباط متفاوت: بخش–کارمند یکبهچند؛ کارمند–مدیر یک ارتباط بازگشتی (کلید خارجی به همان جدول)؛ کارمند–پروژه چندبهچند با صفت «ساعت کار».
-- ساختار سازمانی کامل با CTE بازگشتی WITH Org AS ( SELECT EmployeeId, FullName, ManagerId, 0 AS Level FROM Employee WHERE ManagerId IS NULL UNION ALL SELECT e.EmployeeId, e.FullName, e.ManagerId, o.Level + 1 FROM Employee e JOIN Org o ON e.ManagerId = o.EmployeeId ) SELECT * FROM Org ORDER BY Level, FullName;
ستون ManagerId باید NULLپذیر باشد (مدیرعامل مدیر ندارد). مدل کامل: طراح تعاملی؛ و درس CTE بازگشتی.
۴تمرین ۴ — شبکهی اجتماعی: کاربران پست میگذارند، همدیگر را دنبال میکنند و پستها را لایک میکنند. یک کاربر هر پست را حداکثر یکبار لایک میکند و نمیتواند خودش را دنبال کند.نمایش پاسخ
دو رابطهی چندبهچند: کاربر–کاربر (دنبالکردن) و کاربر–پست (لایک). رابطهی «دنبالکردن» یک M:N بازگشتی است، پس جدول واسط دو ستون کلید خارجی به همان جدول AppUser دارد که باید نامهای متفاوت (Follower و Followee) بگیرند.
CREATE TABLE AppUser ( UserId INT IDENTITY PRIMARY KEY, UserName NVARCHAR(50) NOT NULL UNIQUE, JoinedAt DATETIME2 NOT NULL DEFAULT SYSDATETIME() ); CREATE TABLE Follow ( FollowerId INT NOT NULL REFERENCES AppUser(UserId), FolloweeId INT NOT NULL REFERENCES AppUser(UserId), Since DATETIME2 NOT NULL DEFAULT SYSDATETIME(), PRIMARY KEY (FollowerId, FolloweeId), CONSTRAINT CK_Follow_NotSelf CHECK (FollowerId <> FolloweeId) ); CREATE TABLE Post ( PostId INT IDENTITY PRIMARY KEY, UserId INT NOT NULL REFERENCES AppUser(UserId), Body NVARCHAR(1000) NOT NULL, CreatedAt DATETIME2 NOT NULL DEFAULT SYSDATETIME() ); CREATE TABLE PostLike ( UserId INT NOT NULL REFERENCES AppUser(UserId), PostId INT NOT NULL REFERENCES Post(PostId), LikedAt DATETIME2 NOT NULL DEFAULT SYSDATETIME(), PRIMARY KEY (UserId, PostId) );
قید CK_Follow_NotSelf جلوی دنبالکردن خود را میگیرد و کلید ترکیبی از دنبالکردن تکراری. اگر در طراح تعاملی چنین رابطهای بسازی، ستونهای همنام خودکار پیشوند میگیرند؛ آنها را به FollowerId و FolloweeId تغییر نام بده.