不要使用“智能钥匙”。
这是一个坏主意,称为“智能密钥”或“在密钥中编码信息”。
查看包含this excerpt的this answer:
尽管现在很容易实现智能密钥,但很难建议您自己创建一个不是自然密钥的密钥,因为无论它们有什么优势,它们最终都会遇到麻烦,因为它使数据库更难重构,强加一个难以更改的顺序,并且可能不是您的查询的最佳选择,如果智能键包含非数字字符,则需要进行字符串比较,并且在帮助基于范围的方面不如复合键有效聚合。它还违反了每列都应存储原子值的基本关系准则
智能钥匙也往往超出其原始编码限制
(请注意,座位位置通常由智能键标识,因为它们是行号和跨行的计数。但它们通常也明显地物理地永久固定在该编队中。想象一下它们是否被标记和重新排列。 )
自学数据库设计。
只需用最直接的术语描述您的业务。这就是关系模型数据库和 DBMS 的工作方式。
找到足够的填空句模板来描述您的业务情况:
"customer [cid] has name [firstname] [lastname]
AND customer [cid] has a phone number [phonenumber] of type [type] ..."
"customer [cid] can use credit card #[card_no]"
"seat [seatid] is at row [row] and column [column]"
"seat [seatid] is booked"
"seat [seatid] is temporarily committed to an unfinished booking"
...
对于每个这样的参数化句子模板(又名谓词)都有一个基表,其中空格/参数的名称是列名。表中的每一行都说明了根据其列值填充空白得到的语句 (proposition);不在表中的每一行都表明不是根据其列值填充空白的语句。
然后为每个表找到每个 功能依赖 (FD)。 (当谓词可以用“... AND column = F(column1,...)”的形式表示时,我们称列集 { column1,...} 在功能上确定列列并且FD集→列保持。)然后识别每个候选键 (CK)。 (superkey 是一个列集,它在功能上确定每一列。即,unique,即这些列的值的每个子行仅出现在表的一行中。 CK 是一个不包含更小的超键的超键。)然后找到每个 join 依赖项 (JD)。 (有些谓词对某些数量的 AND 和“...”说“... AND ...”。当每个谓词“...”的表看起来像你只取的时候,有一个 JD它的列来自原始表。)请注意,每个 FD 都带有一个关联的(二进制)JD。
然后规范化你的表格到第五范式(5NF)。这意味着分解(即用谓词为“...”的表替换其中包含 JD“... AND ...”的表),直到每个 JD 都为 CK 所暗示的(即,当来自 CK 的 FD 的 JD 保持时,必须保持。)(出于性能原因,还可以通过组合来非规范化不在 5NF 中的基表。)
参见this answer 和this one。
然后我们通过描述我们想要的行来进行查询。我们通过使用逻辑运算符(即 AND、OR、NOT、FOR SOME、FOR ALL 等)连接基表谓词和函数调用来为我们想要的表提供谓词和/或通过关系运算符连接基表名称来做到这一点(即 JOIN、UNION、MINUS/EXCEPT、PROJECT/SELECT、RENAME/AS) 来给出我们想要的表的值和/或两者(例如 RESTRICT/WHERE)。
两个表的 JOIN 保存了从它们的谓词的 AND 中得出真实语句的行,即作为谓词的行;和 UNION OR, MINUS/EXPT AND NOT;并且表的 PROJECT/SELECT columns 将 FOR SOME all-other-columns 放在其谓词之前;并且 RESTRICT/WHERE 将 AND condition 放在其谓词之后; column 的 RENAME/AS 在其谓词中重命名该参数。所以一个表表达式对应一个谓词:一个表(基表或查询结果)值包含从其(基表或查询表达式)谓词中做出正确语句的行。
见this answer。
约束也是如此,它们是共同描述应用程序情况和数据库状态的真实语句,而不是考虑到可能出现的情况和基表谓词。
见this answer。