基于字段值的CONSTRAINT

时间:2011-12-04 16:11:51

标签: mysql database database-design

所以我有这张桌子

CREATE TABLE meta (
    id BIGINT(20) NOT NULL,
    type VARCHAR(6) NOT NULL,  
    name VARCHAR(64) NOT NULL,
    value LONGTEXT NOT NULL,
        PRIMARY KEY(id, type, name),

) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

类型字段只能有3个可能的值:“article”,“user”或“page”。我为每种内容类型都有3个表。

如果类型是“article”并且id匹配文章表格中的文章ID,我如何添加一个约束来告诉mysql删除“meta”行?还有两个对“用户”和“页面”类型的限制。

现在我有:

CONSTRAINT article_meta FOREIGN KEY(id)
    REFERENCES articles(id) ON DELETE CASCADE ON UPDATE RESTRICT

但它没有考虑“type”字段,因此无论类型值如何都会删除该行...

1 个答案:

答案 0 :(得分:2)

我不认为这是可能的。如果查看the syntax for a CREATE TABLE statement,外键必须具有以下形式:

[CONSTRAINT [symbol]] FOREIGN KEY
      [index_name] (index_col_name,...)
    REFERENCES tbl_name (index_col_name,...)
      [MATCH FULL | MATCH PARTIAL | MATCH SIMPLE]
      [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
      [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]

所以你不能(比方说)在WHEN type = '...' THEN id ELSE NULL END上创建一个外键(因为外键必须是列名,或多个列名,而不是任意表达式),你可以' t(比方说)将外键描述为仅应用WHEN type = '...'(因为没有语法)。

但我想知道 - 你确定拥有一个包含所有这些不同表的元数据的meta表是个好主意吗?如果这些表在语义上有足够的共同点,那么它们共享meta是有意义的,那么它们也应该共享某种父表,entity,它们负责它们的整体ID(在这种情况下,您可以使用多列外键来确保type匹配和所有内容);但是,如果我怀疑它们在语义上没有任何共同点,那么它们不应该有一个共享的meta表,而是应该有一个article_meta表,{{1} }表和user_meta表。否?