这是我的语言表定义,带有自动增量列(DBMS是MySQL):
DROP TABLE IF EXISTS languages;
CREATE TABLE IF NOT EXISTS languages (
language VARCHAR(16) NOT NULL,
PRIMARY KEY (language)
) ENGINE=InnoDB;
这是它的另一个版本,但是应用了UNIQUE约束:
DROP TABLE IF EXISTS languages;
CREATE TABLE IF NOT EXISTS languages (
language_id TINYINT NOT NULL AUTO_INCREMENT,
language VARCHAR(16) NOT NULL,
PRIMARY KEY (language_id),
UNIQUE (language)
) ENGINE=InnoDB;
关于哪个版本更适合使用,我有两种想法。一方面,根据数据库设计理论,第一个定义似乎是正确的,只是因为其中没有额外的垃圾,PRIMARY KEY约束保证不能有两个具有相同值的行,即有例如,“英语”一词在列中不会出现两次,这当然是件好事。但问题是,另一个引用语言列的表中的外键字段必须存储字符串而不是ID号。这只是意味着引用表将整个事物存储在列中,如果应用程序可以提供一个包含预先填充的唯一值的下拉组合框列表,那么使用languages表似乎没有意义。但是,从理论上讲,第一种方式仍然更为正确。
另一方面,第二种方法听起来更实用。为了确保唯一性,我们可以使用UNIQUE约束,并且在引用列中我们有整数而不是字符串,这会占用更少的内存,据我所知,它们在搜索操作中比字符串快得多。
请帮助我顺利完成。
答案 0 :(得分:0)
我在Should an SQL Dictionary table have an IDENTITY column
问了一个类似的问题在这种情况下,我发现没有ID列是正确的决定,因为当我通过代码中的PK以外的任何东西引用数据时,永远不会出现这种情况。也就是说没有外键依赖于该表。
如果您正在查找某些任意数据或将其作为外键引用,我总是支持使用id列,因为它会减小数据库的大小并且可以立即识别它对任何拥有最基本数据库知识的人来说都是外键。
答案 1 :(得分:-1)
第二个版本更加规范化。在数据库设计理论中,存在1NF(第一范式),2NF至6NF的概念。 1NF意味着你只需拥有某种钥匙。 6NF意味着您的数据结构尽可能干净。高标准化听起来不错,但你付出了代价:
如果有疑问,我会一直选择不太复杂的选项。如果您确实需要一天进行完全优化或规范化,则可以在当天更改架构。不确定您的数据库有多大,但如果您仔细地进行重构,那么重构可能会是一块蛋糕。