简体   繁体   English

使用主键的一部分作为外键

[英]Using part of a primary key as a foreign key

I'm building a small MYSQL database, and I currently am having an issue with my entitiy HOME. 我正在建立一个小型的MYSQL数据库,目前我的实体HOME遇到了问题。 Its attributes are ROOM_NUM and BUILD_CODE. 它的属性是ROOM_NUM和BUILD_CODE。 The two make up a composite primary key, with foreign key BUILD_CODE referencing which building it's located in. 两者组成一个复合主键,外键BUILD_CODE引用了它所在的建筑物。

I was wondering if it would be possible to have BUILD_CODE be a single char ('a', 'b', 'c', etc...) and then have a primary key for HOME being something like "A302" or "B205". 我想知道是否可以将BUILD_CODE设为单个字符(“ a”,“ b”,“ c”等),然后将HOME的主键设置为“ A302”或“ B205” ”。 The first character of that primary key would reference BUILD_CODE, with the remaining numbers being the room number. 该主键的第一个字符将引用BUILD_CODE,其余数字为房间号。 Then I'd have a unique single value primary key. 然后,我将拥有一个唯一的单值主键。 The reason I ask is so that I don't have to have multiple foreign keys in my PERSON table referencing to HOME. 我问的原因是我不必在我的PERSON表中有多个引用HOME的外键。

You may use a surrogate key (a sequence) as the primary key of the entity HOME and Use that as the foreign key of the PERSON. 您可以使用代理键(序列)作为实体HOME的主键,并将其用作PERSON的外键。 And then for BUILD_CODE and ROOM_NUM declare a unique key to maintain the uniqueness of the combination. 然后为BUILD_CODE和ROOM_NUM声明一个唯一键,以保持组合的唯一性。

It sounds like HOME needs its own separate identifier. 听起来HOME需要自己的单独标识符。 And it doesn't matter what the ID is...as long as it's unique. 只要ID是唯一的,ID是什么都没关系。

Consider the following: 考虑以下:

mysql> CREATE TABLE HOME (ID INTEGER NOT NULL auto_increment, ROOM_NUM INTEGER, BUILD_CODE VARCHAR(1), PRIMARY KEY(ID));
Query OK, 0 rows affected (0.14 sec)

mysql> CREATE TABLE PERSON(ID INTEGER NOT NULL auto_increment, NAME VARCHAR(255), HOME_ID INTEGER, PRIMARY KEY(ID), FOREIGN KEY(HOME_ID) REFERENCES HOME(ID));
Query OK, 0 rows affected (0.14 sec)

mysql> INSERT INTO HOME (ROOM_NUM, BUILD_CODE) VALUES (302, "A"), (205, "B");
Query OK, 2 rows affected (0.06 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM HOME;
+----+----------+------------+
| ID | ROOM_NUM | BUILD_CODE |
+----+----------+------------+
|  1 |      302 | A          |
|  2 |      205 | B          |
+----+----------+------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO PERSON (NAME, HOME_ID) VALUES ("someone", 1);
Query OK, 1 row affected (0.05 sec)

mysql> SELECT * FROM PERSON;
+----+---------+---------+
| ID | NAME    | HOME_ID |
+----+---------+---------+
|  1 | someone |       1 |
+----+---------+---------+
1 row in set (0.00 sec)

mysql> SELECT PERSON.NAME, HOME.BUILD_CODE, HOME.ROOM_NUM FROM HOME JOIN PERSON ON PERSON.HOME_ID = HOME.ID;
+---------+------------+----------+
| NAME    | BUILD_CODE | ROOM_NUM |
+---------+------------+----------+
| someone | A          |      302 |
+---------+------------+----------+
1 row in set (0.00 sec)

You see, it really doesn't matter that HOME has ID values that don't say much about the rest of its data... You're only using that field as an instrument to join the two together . 您会发现, HOME ID值与其剩余数据并没有多大关系,这真的没关系... 您只是在使用该字段作为将两者结合在一起的工具

Of course, you could just as easily have INSERT ed a concatenation of the BUILD_CODE and ROOM_NUM fields into the ID field... That would be fine too. 当然,你可以很容易地有INSERT爱德的串联BUILD_CODEROOM_NUM领域进入ID字段......这将是罚款了。 But keep in mind that (a) string lookups use more resources than integer lookups, and (b) it's just one more thing that your application needs to maintain (for example: what happens if you start out by calculating the room numbers as A302, but then after seeing larger room numbers, you decide on A00302? You'd have to go through the entire table--and all its associations--and update the ID . It's not terribly ideal). 但是请记住,(a)字符串查找比整数查找使用更多的资源,并且(b)应用程序需要维护的只是一件事(例如:如果您首先通过将房间号计算为A302,会发生什么情况,但是在看到更大的房间号之后,您决定选择A00302吗?您必须遍历整个表(及其所有关联)并更新ID这并不理想)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM