ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

酒店管理系统数据库设计:六张核心表与按时间轴建模的实战要点

酒店管理系统数据库设计:六张核心表与按时间轴建模的实战要点 简介《数据库设计案例-酒店管理系统.doc》是一份面向数据库课程设计、信息系统开发学习的完整参考文档。文档从酒店业务背景切入将中型酒店抽象为饮食、住宿、娱乐三大业务模块并据此划分出总经理、财务、住宿、娱乐四个子系统随后逐一说明各子系统的功能流程并给出职工信息表、部门信息表、收入支出登记表、财务汇总表、客人信息表、房间管理表、娱乐项目表等核心数据表的字段设计。后半部分整理的数据字典覆盖数据项、数据结构、数据流三个层面清晰呈现从业务需求到数据库结构的转换过程有助于理解酒店管理系统各模块如何通过数据表协同关联。资源包共1个文件为doc格式文档压缩包大小约233KB结构完整、可直接引用。已有256人学习该资源适合高校学生、数据库初学者及需要完成酒店管理系统数据建模的开发者参考。1. 一份酒店管理系统数据库设计真正决定成败的不是 ER 图而是时间轴拿到“数据库设计案例-酒店管理系统.doc”这类题目时多数人第一反应是画用户表、房间表、订单表再把外键一连感觉就完事了。但等你真去跑查询、模拟并发订房、做入住换房的时候会发现酒店管理系统和博客、商城最大的不同是它所有的核心业务都压在一个词上时间段。同一间房在同一个晚上只能被一个订单占用这不仅仅是业务规则它必须被表结构、约束、状态机一起兜住。这篇笔记围绕数据库设计按我实际做过的一版酒店管理系统课程设计来拆六张核心表怎么建、范式在哪儿让步、订单状态怎么流转、哪些坑会让你在答辩或验收时翻车。2. 表怎么建酒店管理系统核心六张表与一套可复用的 MySQL 脚本2.1 用户信息表会员和散客不能分成两张表的三个理由很多初学者一看到“用户信息表”就开始拆分一张会员表、一张散客表。理由是散客没有会员等级、没有积分。这个设计在酒店管理系统里是给自己挖坑——散客入住一次后就变成回头客他下次预订时到底算会员还是散客你总不能让他重新注册一遍。常见做法是只建一张 user 表用 member_level 字段区分普通客人和会员级别为 0 时按散客处理。散客在前台登记时也会落一条 user 记录手机号可能为空但身份证号或护照号必填因为公安报送和入住登记都要用。字段设计上注意几点phone 允许为空因为线下散客可能不留手机号但预订用户必须填。id_card 要加密存储不要明文入库。课程设计里哪怕只是 demo也建议加上类似 AES_ENCRYPT 或应用层加密的说明这是答辩时老师喜欢问的安全点。member_level 用 tinyint0 散客、1 普通会员、2 金卡不要用 varchar 存“金卡会员”这种中文排序和统计都会很别扭。created_at 和 updated_at 一定要有后面排查数据问题全靠这两个字段。建表语句CREATE TABLE user ( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 用户ID, username VARCHAR(50) DEFAULT NULL COMMENT 登录用户名散客可为空, password_hash VARCHAR(255) NOT NULL COMMENT 密码哈希推荐bcrypt, phone VARCHAR(20) DEFAULT NULL COMMENT 手机号散客可空, id_card VARBINARY(255) DEFAULT NULL COMMENT 身份证号加密存储, member_level TINYINT NOT NULL DEFAULT 0 COMMENT 0散客 1普通 2金卡, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_phone (phone), KEY idx_member_level (member_level) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;说明username 不是必需的因为散客根本不登录。不要把 username 设成唯一键否则一个手机号注册过的老会员到前台办理入住时前台人员给他新建账号会撞唯一索引。phone 的唯一索引不是必须的如果业务允许一个手机号绑定多个账号比如家人代订就把唯一索引去掉。id_card 用 VARBINARY 是为了说明加密后存的是二进制密文实际项目中也可以在应用层加密后存 VARCHAR。2.2 房间表与房型表为什么不能只在 room 表里写一个 room_type 字段如果只做一张 room 表字段就是room_number、floor、room_type、price、status。看起来简单但问题马上出现同一种房型的价格调整时你要 UPDATE 十几条房间记录统计“豪华大床房总共多少间”要用 LIKE 去匹配字符串如果房型有朝向、床型、面积、早餐等属性room 表会越来越臃肿。我一般会把房型和房间拆成两张表。room_type 存房型的静态属性room 存物理房间的动态属性楼层、房间号、当前状态。这样房间调价只需要改房型表统计入住率时用房间表关联房型表分组即可。room 表里保留 room_type_id 作为外键。CREATE TABLE room_type ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(50) NOT NULL COMMENT 房型名如高级大床房, bed_type VARCHAR(20) NOT NULL COMMENT 床型大床/双床, area DECIMAL(5,2) DEFAULT NULL COMMENT 面积单位平方米, max_occupancy TINYINT NOT NULL DEFAULT 2 COMMENT 最多入住人数, base_price DECIMAL(10,2) NOT NULL COMMENT 挂牌价, breakfast TINYINT NOT NULL DEFAULT 0 COMMENT 是否含早 0/1, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT房型表; CREATE TABLE room ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, room_number VARCHAR(10) NOT NULL COMMENT 房间号如8206, floor TINYINT NOT NULL COMMENT 楼层, room_type_id INT UNSIGNED NOT NULL COMMENT 所属房型, status TINYINT NOT NULL DEFAULT 0 COMMENT 0空闲 1已入住 2脏房 3维修, remark VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY uk_room_number (room_number), KEY idx_room_type (room_type_id), CONSTRAINT fk_room_type FOREIGN KEY (room_type_id) REFERENCES room_type(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT房间表;这里 room.status 是当前时刻的瞬时状态只能用于前台展示“现在这间房能不能安排入住”。它不能回答“下周三这间房有没有被预订”这类问题后者要靠订单表和房间日期表来算。很多课程设计止步于 status 字段导致预订和排房逻辑完全没法做这是个关键认知。2.3 订单表与订单明细一次订三间房怎么设计酒店订单有个特点一个订单可以包含多间房而且每间房的入住离店日期可以不一样。比如一个团队订了三间房其中两间住两晚一间只住一晚。如果只在订单表里放 room_id、check_in_date、check_out_date这个场景直接卡死。所以需要两层结构订单表存订单级公共信息订单明细表存每间房的具体安排。明细表的外键同时指向订单表和房间表。CREATE TABLE booking_order ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL COMMENT 订单号前台展示用, user_id INT UNSIGNED NOT NULL COMMENT 下单用户, guest_name VARCHAR(50) NOT NULL COMMENT 入住人姓名可能和下单人不同, guest_phone VARCHAR(20) NOT NULL COMMENT 入住人联系电话, total_amount DECIMAL(10,2) NOT NULL DEFAULT 0 COMMENT 订单总金额冗余字段, status TINYINT NOT NULL DEFAULT 0 COMMENT 0待支付 1已支付 2已入住 3已离店 4已取消, check_in_date DATE NOT NULL COMMENT 订单最早入住日期, check_out_date DATE NOT NULL COMMENT 订单最晚离店日期, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no), KEY idx_user_id (user_id), KEY idx_status (status), CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES user(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单表; CREATE TABLE booking_item ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, order_id INT UNSIGNED NOT NULL, room_id INT UNSIGNED NOT NULL, room_type_id INT UNSIGNED NOT NULL COMMENT 下单时的房型快照, price_per_night DECIMAL(10,2) NOT NULL COMMENT 每晚单价快照, check_in_date DATE NOT NULL, check_out_date DATE NOT NULL, PRIMARY KEY (id), KEY idx_order_id (order_id), KEY idx_room_date (room_id, check_in_date, check_out_date), CONSTRAINT fk_item_order FOREIGN KEY (order_id) REFERENCES booking_order(id), CONSTRAINT fk_item_room FOREIGN KEY (room_id) REFERENCES room(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单明细表;订单表里放 guest_name 和 guest_phone 是必要的因为下单人和入住人经常不是同一个人。total_amount 是冗余字段它的值由应用层在生成订单时根据明细算好写入不要在查询时再去 SUM 明细表——订单列表页要分页展示每次都 SUM 会拖慢查询。我特意在 booking_item 里加了 price_per_night 快照字段。房型价格后续会调但订单生成那一刻的价格必须被固定下来。这个字段是第 3 章要展开讲的范式让步的核心。2.4 房态日程表解决“某间房某晚是否可订”的关键一张表只靠 room.status 和订单明细你依然算不出“8206 房间 7 月 15 日晚上是否空闲”。你当然可以用一条 SQL 去查 booking_item 里有没有和该日期重叠的记录但每次排房都这样做数据库压力很大而且很容易写错区间条件。更稳妥的做法是加一张 daily_room_status 表按“房间日期”粒度为每一天生成一条记录。这张表不是必需的但它能把“某晚某房是否可售”从复杂区间查询变成一次主键查询极大简化逻辑。CREATE TABLE daily_room_status ( room_id INT UNSIGNED NOT NULL, biz_date DATE NOT NULL COMMENT 业务日期, status TINYINT NOT NULL DEFAULT 0 COMMENT 0可售 1已预订 2已入住 3维修, order_item_id INT UNSIGNED DEFAULT NULL COMMENT 占用该日的订单明细ID, PRIMARY KEY (room_id, biz_date), KEY idx_date_status (biz_date, status), CONSTRAINT fk_daily_room FOREIGN KEY (room_id) REFERENCES room(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT房态日程表;这张表的主键是 room_id biz_date意味着每一天每一间房只有一条记录。当订单支付成功后应用层需要把订单覆盖的所有日期逐条写入或更新这张表。它的代价是数据量会膨胀但酒店的房间数一般在一百到三百间一年也就十万条级别完全扛得住换来的是排房判断极快。这个表也是很多一线酒店管理系统 PMS 的做法不是说 status 字段没用而是它只管“当下”这张表管“未来”。3. 关系与范式第三范式在酒店系统里哪些地方必须让步3.1 ER 图里最容易画错的四条关系先捋一下表之间的关系。用户和订单是一对多一个用户可以有多个订单订单和订单明细是一对多订单明细和房间是多对一房间和房型是多对一。这四条关系里最容易画错的是订单明细和房间的关系——很多人会画成订单和房间的多对多然后通过一张中间表关联。但实际上订单明细表本身就承担了中间表的作用它既是订单的子表又通过外键关联房间不需要额外再建一张“订单房间关联表”。四个实体之间还有一条容易被忽略的关系daily_room_status 和 booking_item 是多对一。订单明细的一条记录一间房住两晚会对应 daily_room_status 里的两条记录。如果你在 ER 图上漏掉这张表后面写“查询某天可售房间”的 SQL 时会发现无从下手。画 ER 图时还有一个常见争议订单表要不要外键关联用户表。我的做法是关联但在物理设计上不给 user_id 加外键约束只加普通索引。原因是订单表是核心热表外键约束会在每次插入时检查父表高并发下会放大锁竞争。逻辑关系靠应用层保证物理外键能不加就不加。这条经验在课程设计答辩时你可以主动讲出来老师会认为你考虑过真实场景。3.2 房价快照故意违反第三范式反范式设计第三范式要求表中不能存在传递依赖。order_item 里的 price_per_night 依赖的是 room_type.base_price而 room_id 依赖房型严格按照范式推导price_per_night 属于冗余字段。但如果你遵守第三范式订单生成后不存价格快照那么三个月后房型调价你要算历史订单的营收就全乱了——只能用下单时间去找当时的房型价格而房型价格如果也在同一张表里被覆盖更新历史价格彻底丢失。所以正确做法是双轨制room_type 表里的 base_price 存的是“当前挂牌价”随时可以改booking_item 表里的 price_per_night 存的是“成交价快照”永远不改。这样统计历史营收直接 SUM price_per_night不需要回溯。这个设计在数据库设计里叫“快照模式”和博客系统-数据库设计那种纯范式模型不一样酒店、电商订单、外卖系统的核心订单表都有这个影子。另外一个常见的范式问题订单表的 total_amount 也是冗余字段理论上可以从明细表聚合算出。但列表页要频繁展示订单金额每次 JOIN 明细再 SUM查询成本高且代码难读。存冗余字段的本质是拿空间换查询时间做这个设计时要在文档里写明“该字段由应用层维护来源为明细表聚合”这样答辩时不会被质疑不一致。3.3 入住登记表业务数据永远不能覆盖很多人把“入住登记”和“订单明细”当成一回事订单支付了、客人入住了就是把订单状态改成“已入住”而已。这是酒店管理系统和电商系统最大的不同——电商订单履约后订单本身仍然是唯一记录但酒店客人入住后会产生一条新的实名登记记录包含入住人证件信息、实际房间号、实际入住时间、同住人信息。这条记录是给公安报送和财务审计用的必须独立建表。CREATE TABLE stay_record ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, order_item_id INT UNSIGNED NOT NULL COMMENT 关联订单明细, room_id INT UNSIGNED NOT NULL, guest_name VARCHAR(50) NOT NULL, id_card VARBINARY(255) NOT NULL COMMENT 证件密文, check_in_time DATETIME NOT NULL COMMENT 实际入住时间, check_out_time DATETIME DEFAULT NULL COMMENT 实际离店时间, remark VARCHAR(255) DEFAULT NULL, PRIMARY KEY (id), KEY idx_order_item (order_item_id), KEY idx_room_time (room_id, check_in_time), CONSTRAINT fk_stay_order_item FOREIGN KEY (order_item_id) REFERENCES booking_item(id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT入住登记表;stay_record 的引入意味着你的系统要处理一个边界情况客人预订的是 8206 房到店后因为 8206 还没打扫完先安排到 8210 房住了一晚第二天再换回 8206。这个场景在后面的避坑章节会展开这里先记住一个原则订单明细管的是“预订时的契约”入住登记表管的是“实际发生的住宿事实”两者可以不一致但必须都有记录。这就是为什么不能只用订单明细做财务结算——实际入住房间和预订房间不一致时按预订房型结算就会出账目差错。4. 订单状态机与并发控制酒店管理系统最容易翻车的地方4.1 六个状态怎么流转从待支付到已取消订单状态字段设计成数字枚举比字符串更省空间但文档里必须配一张状态流转表否则后来接手代码的人根本不敢改状态。我按实际项目经验定义六个状态状态值名称允许流转到0待支付1 已支付 / 4 已取消1已支付2 已入住 / 4 已取消限未入住前2已入住3 已离店3已离店终态4已取消终态5已 noshow终态这个状态机里容易被忽略的是状态 4 到状态 1 的恢复操作。客人取消订单后发现搞错了要求恢复预订这种情况常见。你不应该把状态直接从 4 改成 1而应该重新走一遍“创建订单→锁定房间→支付”的流程因为取消时房间可能已经放给别的客人了。状态机一旦开历史倒车数据一致性就失控了。noshow预付款未到店在酒店行业非常常见尤其是 OTA 渠道的订单。很多课程设计不设计这个状态结果就是订单一直挂在“已支付”既不能算收入房间也被白白占用。处理办法是设置一个入住截止时间比如凌晨 2 点前未办理入住的已支付订单系统自动或由前台手动把状态置为 5同时释放房间。4.2 并发抢房唯一索引、锁表还是乐观锁“两个客人同时预订同一间房同一晚”是酒店管理系统并发控制的核心考题。如果只靠应用层先 SELECT 再 INSERT中间的时间差就会产生重复订单。可行方案有三个复杂度从低到高。方案一是在 daily_room_status 上做唯一约束。因为这张表的主键是 room_id biz_date当两个事务同时插入相同房间相同日期的记录时后提交的那个会触发主键冲突应用层捕获异常后提示“该房间已被预订”。这是最推荐课程设计使用的方案简单、有效、不需要额外字段。-- 伪代码事务内先尝试插入冲突则说明房间被占 INSERT INTO daily_room_status (room_id, biz_date, status, order_item_id) VALUES (101, 2025-07-15, 1, 10001); -- 如果抛 Duplicate entry 异常回滚事务并提示前台换房这个方案的边界是你的业务允许同一间房在同一晚卖给两个不同的订单吗不允许。所以唯一主键直接从数据库层面杜绝了这种可能比任何应用层判断都可靠。方案二是用 SELECT ... FOR UPDATE 对房间记录加锁。事务 A 锁住 room 表里 id101 的行事务 B 再查这行会被阻塞直到 A 提交。这个方案的缺点是锁粒度太大一个房间被锁其他无关操作也可能被阻塞而且万一事务没及时提交会拖垮整个连接池。方案三是乐观锁给 room 表加 version 字段每次更新时检查 version 是否匹配。但乐观锁适合读多写少的场景酒店预订是典型的写多场景乐观锁更新失败率会很高客人体验差。所以我的建议是课程设计用唯一索引方案生产环境用数据库的唯一约束加 Redis 分布式锁双层兜底。4.3 区间查询为什么不能直接写 BETWEEN订单明细表里有 check_in_date 和 check_out_date查询某天某房是否被占用时新手容易写出这样的 SQLSELECT * FROM booking_item WHERE room_id 101 AND check_in_date 2025-07-15 AND check_out_date 2025-07-15;这个 SQL 在数据量小的时候没问题但注意一个边界check_out_date 表示离店日期客人 7 月 15 日入住、7 月 17 日离店那么 7 月 17 日当晚房间是空的。上面的 SQL 条件 check_out_date 2025-07-15 会把 7 月 17 日离店的订单也算作占用导致房间少卖一晚。正确写法是 check_out_date 2025-07-15因为离店日当天房间不再占用。这个坑非常隐蔽很多教材里的示例代码都写错。避免它的最好办法就是使用 daily_room_status 表——直接查 biz_date 2025-07-15 的状态即可根本不涉及区间判断。如果你在文档里能解释清楚为什么要额外建这张日程表理由就是“为了避免区间查询的边界错误和性能问题”这个设计意图本身就是加分项。5. 避坑记录酒店管理系统数据库设计的五个血泪教训5.1 已支付订单取消了房态日程没有同步释放现象客人在线支付后取消订单前端显示取消成功但这间房在 daily_room_status 里仍然是“已预订”状态后续客人无法预订。原因取消订单的代码只更新了 booking_order.status没有删除或更新 daily_room_status 中对应日期段的记录。两个表的数据由不同接口维护漏了一步。解决把“取消订单”做成一个独立事务事务内同时更新订单状态、回滚房态日程、写操作日志。用事务保证要么全部成功要么全部失败。另外定时任务里加一个对账脚本把状态为“已支付”但超过入住日期未入住的订单列为异常清单由前台人工确认。这条经验也适用于换房和离店场景每改一次订单都要问“房态日程表跟上了吗”。5.2 换房后直接 UPDATE booking_item把历史记录抹掉了现象客人从 8206 换到 8210开发人员直接 UPDATE booking_item SET room_id 8210 WHERE id xxx。结果财务核对时发现 8206 那晚没有入住记录但订单显示客人住了 8206。原因把“预订房间”和“实际入住房间”混为一谈。订单明细代表客人预订时的契约实际入住信息应该写入 stay_record而不是覆盖订单明细。换房是住宿事实的变化不是预订契约的变化。解决订单明细保持不变在 stay_record 里新增一条记录写入实际房间号、实际入住和离店时间。如果客人中间换过房就产生两条 stay_record分别记录不同时间段的实际房间。退房结算时按 stay_record 计算实际住宿费用按订单明细计算应收费用两者差异单独列一项“换房差价”。5.3 折扣价覆盖基础价导致日报表对不上账现象前台给金卡会员打了八折直接 UPDATE booking_item SET price_per_night 原价 * 0.8。月底统计房型平均房价时发现数据比门市价低得离谱且无法区分哪些订单是折扣订单。原因price_per_night 字段承担了两个职责——成交价快照和折扣记录。这个字段应该是实际成交价但不能只存一个最终值折扣前价格和折扣率也要留底。解决把价格字段拆成三个base_price_snapshot下单时挂牌价、discount_rate折扣率默认 1.00、actual_price实际成交价。actual_price 在应用层计算后写入报表统计时既可以用 actual_price 算营收也可以用 discount_rate 分析折扣占比。注意下单后改折扣要在单独的“改价记录表”里留操作人和时间否则财务审计时说不清是谁改的价格。5.4 时区问题凌晨订单的日期归属错了现象客人 7 月 15 日晚上 23:50 在线上平台下单预订的是 7 月 16 日入住。后台跑批统计“当日新增订单”时这张订单被算进了 7 月 16 日但财务口径里它属于 7 月 15 日的订单量。原因created_at 用的是服务器本地时间而订单的业务日期应该用下单时客人所在时区的时间。如果服务器设在东八区订单表里的 created_at 本身没问题但统计“下单日期”要用下单时的北京时间而不是服务器 UTC 时间转换后的结果。解决所有日期时间字段统一用 DATETIME 存北京时间不要用 TIMESTAMP它受时区设置影响服务器时区一改历史数据全部偏掉。统计日报时用 biz_date 字段而不是 created_atbiz_date 由业务层在创建订单时按北京时间写入。如果系统要对接 OTA 渠道还要额外注意渠道传入的时区参数统一在入口处转换。5.5 索引建了一大堆查询还是慢现象daily_room_status 只有几万条数据但查“某天可售房间列表”需要 2 秒。EXPLAIN 一看走了全表扫描。原因索引建得不对。常见错误是在 status 字段上建单列索引但查询条件是 biz_date 某天 AND status 0日期的区分度远高于状态值优化器很可能选择只用日期索引或者干脆全表扫。另一个错误是把 order_item_id 也建了唯一索引但这个字段大量为 NULLNULL 在索引中有特殊处理查询效率并不好。解决按查询模式重建索引。可售房间查询的主驱动条件是日期所以复合索引 (biz_date, status) 效果最好。如果还要关联 room 表查楼层和房型测试后考虑把 room 表的常用字段冗余到 daily_room_status 里减少 JOIN。索引不是越多越好每个索引都占用写入开销。课程设计里可以通过 EXPLAIN 展示索引选择过程这条细节很能体现你在认真做性能分析。6. 把设计落成一份能过审的 doc 文档图表、数据字典与验收清单最后的交付物是“数据库设计案例-酒店管理系统.doc”不是一份建表 SQL 就能交差的。作为课程设计或项目文档老师或评审最关心三件事表设计是否完整、ER 关系是否清晰、业务场景有没有考虑到位。我建议按这样的文档结构组织内容封面与需求概述用 300 字说清楚系统解决什么问题别抄百度百科式的系统介绍直接写“支持散客和会员预订、前台入住退房、房态管理、财务对账”四件事。概念结构设计一张全局 ER 图。用 MySQL Workbench 或 drawio 画导出 PNG 插入文档。ER 图里必须出现 daily_room_status这是体现你理解业务的关键表。逻辑结构设计每个表建一个数据字典表格包含字段名、类型、是否可空、默认值、说明。数据字典覆盖 user、room_type、room、booking_order、booking_item、daily_room_status、stay_record 七张表。物理结构设计说明采用的 MySQL 版本、InnoDB 引擎、utf8mb4 字符集、各表索引设计。重点说明不要在订单表上滥用外键约束用普通索引加逻辑关联代替并给出理由。业务场景与 SQL 示例写“查询 7 月 15 日可售大床房”“查询某订单明细”“统计本月入住率”三个典型查询语句配合执行结果截图。状态机与约束说明订单状态流转图、房态日程唯一约束、并发抢房方案。文档里还有一个容易被问到的问题为什么不把入住客人的信息直接存在订单表里而要拆出 stay_record。文档里必须用一段话解释“订单是契约入住登记是事实”。这个设计思路也是区分你的设计是套模板还是真理解业务的分水岭。我的习惯是文档写完后自己按“预订→支付→入住→换房→退房→取消订单”六个流程各跑一遍 SQL把每张表的数据变化截图贴进文档。数据变更前后的对比截图比任何文字都更有说服力。最后再检查一遍每个外键字段两边类型是否一致、所有日期边界条件是否用了大于号、并发抢房是否做了唯一约束。这些细节都过关这份酒店管理系统数据库设计案例就真正能落地了希望帮到你。本文还有配套的精品资源点击获取
返回列表