简体   繁体   English

如何将数据插入到涉及外键依赖项的多个表中(MySQL)

[英]How to insert data to multiple tables with foreign key dependencies involved (MySQL)

I am looking for the best-practice way to insert data to multiple MySQL tables where some columns are foreign key dependencies. 我正在寻找将数据插入多个MySQL表的最佳实践方法,其中一些列是外键依赖项。 Here is an example: 这是一个例子:

Table: contacts
--------------------------------------------------------------------
|  contact_id  |  first_name  | last_name  |  prof_id  |  zip_code  |
--------------------------------------------------------------------

The 'contacts' table has PRIMARY KEY (contact_id) which simply auto_increments, and FOREIGN KEY (prof_id) REFERENCES 'profession' table, FOREIGN KEY (zip_code) REFERENCES 'zip_code' table. 'contacts'表有PRIMARY KEY(contact_id),它只是auto_increments,和FOREIGN KEY(prof_id)REFERENCES'专业'表,FOREIGN KEY(zip_code)REFERENCES'zip_code'表。 Those tables would look something like this: 这些表看起来像这样:

Table: profession
----------------------------
|  prof_id  |  profession  |
----------------------------

where 'prof_id' is an INT NOT NULL AUTO_INCREMENT PRIMARY KEY, and 其中'prof_id'是INT NOT NULL AUTO_INCREMENT PRIMARY KEY,和

Table: zip_code
--------------------------------
|  zip_code  | city  |  state  |
--------------------------------

where 'zip_code' is an INT(5) NOT NULL PRIMARY KEY. 其中'zip_code'是INT(5)NOT NULL PRIMARY KEY。

I have a new person I want to add a record for, let's say: 我有一个新人想要添加记录,让我们说:

first_name = 'John', last_name = 'Doe', profession = 'Network Administrator', city = 'Sometown', state = 'NY', zip_code = 12345

Here's what I'm trying to do: I want to take that information and insert it into the appropriate tables and columns. 这是我正在尝试做的事情:我想获取该信息并将其插入适当的表和列中。 To prevent duplicate values in a column (like profession for example) I'd first want to make sure there isn't already an entry for "Network Administrator", and if there was I'd like to just get its key value, if not insert it and then get its key value. 为了防止列中的重复值(例如专业),我首先要确保没有“网络管理员”的条目,如果有,我只想获取其键值,如果不插入它然后获取其键值。 The same goes for zip_code, city, state - if it exists just use that zip_code key, otherwise insert the new data and grab the associated key. 对于zip_code,city,state也是如此 - 如果它存在则只使用该zip_code键,否则插入新数据并获取相关密钥。 Then, finally, I'd want to enter the new contact to 'contact' table using the supplied information, including the appropriate key values associated with profession and location from the other tables. 然后,最后,我想使用提供的信息将新联系人输入“联系人”表,包括与职业相关的关键值以及其他表中的位置。

My question is, what is the best recommended way to do this? 我的问题是,推荐的最佳方法是什么? I know I can sit here and write single statements to check if the given profession exists, if not then enter it, then get the key. 我知道我可以坐在这里写单个陈述以检查给定的职业是否存在,如果不存在则输入,然后获取密钥。 Do the same for zip_code. 为zip_code做同样的事情。 Then finally Insert all of that into contacts, however I know there must be a better way to accomplish this in fewer (perhaps one) statement, especially considering this could cause a problem if, say, the database went offline for a moment in the midst of all of this. 然后最后将所有这些插入到联系人中,但是我知道必须有更好的方法来在更少(可能是一个)语句中完成此操作,特别是考虑到这可能会导致问题,例如,如果数据库在中间离线了一会儿所有这一切。 Is there a way to use JOINs with this INSERT to essentially have everything cascade into the correct place? 有没有办法在这个INSERT中使用JOIN来基本上将所有内容级联到正确的位置? Should I look to handle this with a TRANSACTION series of statements? 我应该用TRANSACTION系列语句来处理这个问题吗?

I am in the learning stage with SQL but I feel that the books and resources I have used thus far have sort of jumped to using nested queries and JOINS under the assumption we have all of these tables of data already populated. 我正处于使用SQL的学习阶段,但我觉得到目前为止我使用的书籍和资源有点跳跃到使用嵌套查询和JOINS,假设我们已经填充了所有这些数据表。 I'm even open to suggestions on WHAT I should be Googling to better learn this, or any resources that can help fill this gap. 我甚至乐于接受关于我应该谷歌搜索什么以获得更好的知识的建议,或任何有助于填补这一空白的资源。 Ideally, I'd love to see some functioning SQL code to do this though. 理想情况下,我希望看到一些功能正常的SQL代码来做到这一点。 If necessary, assume PHP as the language to interact with the database, but command-line sql is what I was aiming for. 如果需要,假设PHP作为与数据库交互的语言,但命令行sql是我的目标。 Thanks ahead of time, hopefully I made everything clear. 提前谢谢,希望我把一切都清楚了。

In short, you want to use transactions (more doc on this) so that your inserts are atomic . 简而言之,您希望使用事务 (更多文档),以便您的插入是原子的 This is the only way to guarantee that all (or none) of your data will be inserted. 这是保证插入所有(或没有)数据的唯一方法。 Otherwise, you can get into the situation you describe where the database becomes unavailable after some insertions and others are unable to complete. 否则,您可以进入您描述的情况,在某些插入后数据库变得不可用而其他数据库无法完成。 A transaction tells the database that what you are doing is all-or-nothing and so it should roll back if something goes wrong. 事务告诉数据库你正在做什么是全有或全无,所以如果出现问题它应该回滚。

When you are using synthetic primary keys, as you are, PHP and other languages provide mechanisms for getting the last inserted id. 当您使用合成主键时,PHP和其他语言提供了获取最后插入ID的机制。 If you want to do it entirely in MySQL you can use the LAST_INSERT_ID() function. 如果你想在MySQL中完全使用它,你可以使用LAST_INSERT_ID()函数。 You will end up with code like this: 你最终会得到这样的代码:

START TRANSACTION;
INSERT INTO foo (auto,text)
    VALUES(NULL,'text');         # generate ID by inserting NULL
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # use ID in second table
COMMIT;

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

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