Database design 如果一个对象有多种类型,object.type什么时候应该是字符串,什么时候应该是外键?

Database design 如果一个对象有多种类型,object.type什么时候应该是字符串,什么时候应该是外键?,database-design,foreign-keys,associations,lookup-tables,Database Design,Foreign Keys,Associations,Lookup Tables,比如说,我有一些书,可以是浪漫小说、小说或神秘小说。我有两个现实的选项来存储这些数据。一种是在我的books表中有一个type列,它是一个值为“浪漫”、“小说”或“神秘”的字符串。另一个是创建一个book_types表并将类型存储在其中。然后我的书将有一个type_id外键引用book_types表 我的问题是如何选择最好的?我已经看到Restful认证Rails插件中使用的string方法,它包含有关用户状态的信息—“非活动”、“活动”、“挂起” 考虑到我将一直查询这些信息,使用查找表方法是否

比如说,我有一些书,可以是浪漫小说、小说或神秘小说。我有两个现实的选项来存储这些数据。一种是在我的books表中有一个type列,它是一个值为“浪漫”、“小说”或“神秘”的字符串。另一个是创建一个book_types表并将类型存储在其中。然后我的书将有一个type_id外键引用book_types表

我的问题是如何选择最好的?我已经看到Restful认证Rails插件中使用的string方法,它包含有关用户状态的信息—“非活动”、“活动”、“挂起”

考虑到我将一直查询这些信息,使用查找表方法是否会影响性能


谢谢

如果没有更多的信息可以存储,字符串通常是很好的(虽然这是一个非瞬时值,所以不是正常形式)

但是,这似乎是一个很好的表候选,因此您可能希望对类别做更多的处理,因此它应该是一个参考表,imo.

我将使用fk。 重复的信息更少

编辑: 更好的解决方案: MySql代码:

CREATE TABLE books
(
    id int AUTO_INCREMENT          not null,
    book_type enum('romance', 'fiction', 'mystery')     not null,
    ....
);

外键方法将表现得更好。字符串比较会减慢速度。比较数字要快得多


如果要进一步加快查询速度,请在用于引用外键的列上添加索引。与主键不同,不会自动为外键创建索引。

在大多数情况下,使用外键到单独表的方法是最好的-优点:

  • 这张单独的桌子给你一个 验证条目的可扩展方法。将硬编码的检查约束放入表定义中 然后需要一个ALTER表来添加 新型

  • 如果您出于某种原因需要更改类型文本(例如,对于一个蹩脚的示例,“浪漫”->“女性小说”),则只需对查找表进行轻量级更新

  • 可以想象,您的类型还没有条目,单独的表允许您使用外部联接将该类型包括在SQL结果集中

  • 从界面的角度来看,一个单独的表可以让您轻松地生成一个类型下拉列表,这些类型不需要在UI中进行硬编码


就性能而言,如果FK上有适当的索引,任何RDBMS引擎都会表现良好-连接是RDBMS的设计目标。

并非所有数据库都具有枚举类型。这样添加新类别容易吗?@uncleo:这就是我写“mysql代码”的原因。关于添加新类别:显然,正确的解决方案取决于他需要什么。如果书的类型不会改变,enum也没关系。我是说这是一个合理的问题。我以前从未使用过enum。我想知道如果将列修改为不同的枚举会发生什么。如果在末尾添加一个新值,它会正确地保留旧值吗?@uncleo:噢,我的错。它可以通过一个alter表来完成。类似于:altertablebooks修改列book_-type枚举(“浪漫”、“虚构”、“神秘”、“新_-type”);