如何解決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。

关注微信公众号

注意!

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



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