如何解决A / B键问题?

[英]How to solve the A/B key problem?


I have a table my_table with these fields: id_a, id_b. So this table basically can reference either an row from table_a with id_a, or an row from table_b with id_b. If I reference a row from table_a, id_b is NULL. If I reference a row from table_b, id_a is NULL.

我有一个表my_table与这些字段:id_a,id_b。所以这个表基本上可以引用table_a中带有id_a的行,或者带有id_b的table_b中的行。如果我从table_a引用一行,则id_b为NULL。如果我从table_b引用一行,则id_a为NULL。

Currently I feel this is my only/best option I have, so in my table (which has a lot more other fields, btw) I will live with the fact that always one field is NULL.

目前我觉得这是我唯一的/最好的选择,所以在我的表格中(其他字段还有很多,顺便说一下)我总是认为总是有一个字段是NULL。

If you care what this is for: If id_a is specified, I'm linking to a "data type" record set in my meta database, that specifies a particular data type. like varchar(40), for example. But if id_b is specified, I'm linking to a relationship definition recordset that specifies details about an relationship (wheather it's 1:1, 1:n, linking what, with which constraints, etc.). The fields are called a little bit better, of course ;) ...just try to simplify it to the problem.

如果您关心这是为了什么:如果指定了id_a,我将链接到我的元数据库中的“数据类型”记录集,该记录指定特定的数据类型。比如varchar(40)。但是如果指定了id_b,我将链接到关系定义记录集,该记录集指定关系的详细信息(通过它是1:1,1:n,链接什么,使用哪些约束等)。当然,字段被称为更好一点;)...只是尝试将其简化为问题。

Edit: If it matters: MySQL, latest version. But don't want to constrain my design to MySQL specific code, as much as possible.

编辑:如果重要:MySQL,最新版本。但是不要想尽可能地将我的设计限制在MySQL特定代码中。

Are there better solutions?

有更好的解决方案吗?

5 个解决方案

#1


4  

A and B are disjoint subtypes in your model.

A和B是模型中不相交的子类型。

This can be implemented like this:

这可以这样实现:

refs    (
        type CHAR(1) NOT NULL, ref INT NOT NULL,
        PRIMARY KEY (type, ref),
        CHECK (type IN ('A', 'B'))
        )

table_a (
        type CHAR(1) NOT NULL, id INT NOT NULL,
        PRIMARY KEY (id),
        FOREIGN KEY (type, id) REFERENCES refs (type, id),
        CHECK (type = 'A'),
        …)

table_b (
        type CHAR(1) NOT NULL, id INT NOT NULL,
        PRIMARY KEY (id),
        FOREIGN KEY (type, id) REFERENCES refs (type, id) ON DELETE CASCADE,
        CHECK (type = 'B'),
        …)

mytable (
        type CHAR(1) NOT NULL, ref INT NOT NULL,
        FOREIGN KEY (type, ref) REFERENCES refs (type, id) ON DELETE CASCADE,
        CHECK (type IN ('A', 'B')),
        …)

Table refs constains all instances of both A and B. It serves no other purpose except policing referential integrity, it won't even participate in the joins.

表refs包含A和B的所有实例。除了监管引用完整性之外,它没有任何其他用途,它甚至不参与连接。

Note that MySQL accepts CHECK constraints but does not enforce them. You will need to watch your types.

请注意,MySQL接受CHECK约束但不强制执行。你需要看你的类型。

You also should not delete the records from table_a and table_b directly: instead, delete the records from refs which will trigger ON DELETE CASCADE.

您也不应该直接从table_a和table_b中删除记录:而是从refs中删除将触发ON DELETE CASCADE的记录。

#2


2  

Create a parent "super-type" table for both A and B. Reference that table in my_table.

为A和B创建父“超类型”表。在my_table中引用该表。

#3


1  

Yes, there are better solutions.

是的,有更好的解决方案。

However, since you didn't describe what you're allowed to change, it's difficult to know which alternatives could be used.

但是,由于您没有描述允许更改的内容,因此很难知道可以使用哪些替代方法。

Principally, this "exclusive-or" kind of key reference means that A and B are actually two subclasses of a common superclass. You have several ways to changing the A and B tables to unify them into a single table.

原则上,这种“异或”类的关键引用意味着A和B实际上是公共超类的两个子类。您有多种方法可以更改A和B表以将它们统一到一个表中。

One of which is to simply merge the A and B table into a big table.

其中之一就是简单地将A和B表合并为一个大表。

Another of which is to have a superclass table with the common features of A and B as well as a subtype flag that says which subtype it is. This still involves a join with the subclass table, but the join has an explicit discriminator, and can be done "lazily" by the application rather than in the SQL.

另一个是拥有一个具有A和B共同特征的超类表以及一个子类标志,该子标志指出它是哪个子类型。这仍然涉及与子类表的连接,但是连接具有显式鉴别器,并且可以由应用程序“懒惰地”而不是在SQL中完成。

#4


0  

I see no problem with your solution. However, I think you should add CHECK constraints to make sure that exactly one of the fields is null.

我认为您的解决方案没有问题。但是,我认为你应该添加CHECK约束以确保其中一个字段为null。

#5


0  

you know, it's hard to tell if there are any better solutions since you've stripped the question of all vital information. with the tiny amount that's still there i'd say that most better solutions involve getting rid of my_table.

你知道,因为你已经剥夺了所有重要信息的问题,所以很难说是否有更好的解决方案。只有少量的数据仍然存在,我会说最好的解决方案是摆脱my_table。

智能推荐

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:http://www.itdaan.com/blog/2009/12/30/720075d54882a22b0209dbf4eb889851.html



 
© 2014-2019 ITdaan.com 粤ICP备14056181号  

赞助商广告