代码之家  ›  专栏  ›  技术社区  ›  Tony

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

  •  2
  • Tony  · 技术社区  · 16 年前

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

    我的问题是如何选择最好的?我已经看到了restful authentication rails插件中使用的字符串方法,它包含有关用户状态的信息-“不活动”、“活动”、“挂起”…

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

    谢谢!

    4 回复  |  直到 16 年前
        1
  •  3
  •   UncleO    16 年前

    外键方法的性能会更好。字符串比较会减慢速度。比较数字要快得多。

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

        2
  •  1
  •   Luke Schafer    16 年前

    如果没有更多的信息存储在某个对象上,那么字符串通常很好(尽管这是一个非瞬时值,所以它不是正常形式)。

    不过,这似乎是一个很好的表格候选,因此您可能需要对类别做更多的工作,因此它应该是一个参考表,IMO。

        3
  •  1
  •   dpbradley    16 年前

    在大多数情况下,对单独表使用外键的方法是最佳的-优势:

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

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

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

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

    就性能而言,只要在fk上有适当的索引,任何RDBMS引擎都能很好地执行连接,这就是RDBMS设计的目的。

        4
  •  0
  •   Macarse    16 年前

    我会用FK。 复制的信息更少。

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

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