3

这是我的带有自动增量列的语言表定义(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 约束保证不能有两行具有相同的值,也就是说,有例如,“English”这个词不可能在列中出现两次,这当然是一件好事。但是这样做的问题是另一个表中引用语言列的外键字段必须存储字符串而不是 ID 号。这仅仅意味着引用表将把整个内容存储在列中,如果应用程序可以提供一个下拉组合框列表,其中包含预先填充的唯一值,那么拥有语言表似乎没有意义。但,

另一方面,第二种方法听起来更实用。为了确保唯一性,我们可以使用 UNIQUE 约束,并且在引用列中使用整数而不是字符串,这往往会占用更少的内存,据我所知,它们在搜索操作期间比字符串快得多。

请帮我弄清楚这一点。

4

2 回答 2

1

我在这里问了一个类似的问题如果 SQL 字典表有一个 IDENTITY 列

在那种情况下,我发现没有 ID 列是正确的决定,因为我永远不会通过代码中的 PK 以外的任何方式引用数据。那就是没有依赖于该表的外键。

如果您正在查找一些任意数据或将其作为外键引用,我总是主张使用 id 列,因为它会减小数据库的大小并且可以立即识别它是外键任何拥有最基本数据库知识的人的关键。

于 2013-04-10T19:46:47.950 回答
-1

第二个版本更加规范化。在数据库设计理论中有 1NF(第一范式)、2NF 到 6NF 的概念。1NF 意味着您只有某种密钥。6NF 意味着您的数据结构尽可能干净。高标准化听起来不错,但你付出了代价:

  • 更复杂的查询和插入操作
  • 由于所有这些复杂性而导致性能下降

如有疑问,我总是会选择不太复杂的选项。如果有一天你真的需要全面优化或规范化,你可以在那天改变你的架构。不确定你的数据库有多大,但如果你仔细地重构,重构可能是小菜一碟。

于 2013-04-10T20:22:07.570 回答