簡體   English   中英

MySQL-外鍵和自動生成的ID

[英]MySQL - Foreign key and auto-generated ID

在我的應用程序中,我有一個從其他組件接收對象並將其插入MySQL DB的組件。 目前,我正在緩沖對象,並且偶爾(幾秒鍾)使用批處理(使用JDBC,而不是休眠)將對象插入數據庫。

我想將此對象分解為2個對象,然后是兩個緩沖區,最后將它們插入2個不同的表中。

我的第一個想法是使用MySQL自動生成的ID將表中的兩個子對象綁定在一起(作為外鍵)。

我的問題是-當我插入“子”對象時,如何知道“父親”對象的自動生成的ID?

我的想法是:

  1. 在拆分對象之前生成我自己的ID,然后自己將ID發送給數據庫,而無需使用MySQL自動生成的ID。
  2. 使用將插入第一個對象的存儲過程,使用MySQL的LAST_INSERT_ID();

你怎么看?

一種解決方案是像在此問題中一樣,將兩個記錄插入同一事務中。 JDBC:在同一事務中創建的PK的外鍵

那是:

  1. 初始化交易。
  2. 做父親的第一次插入。
  3. 檢索生成的父親ID。
  4. 使用父親ID對孩子進行第二次插入。
  5. 提交交易。

也許有幫助(您也可以在普通SQL中使用LAST_INSERT_ID(),不僅可以在過程內部使用),另請參見http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html

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

鑒於OP在不同的線程上運行INSERT,因此需要預先分配ID-您可以使用序列安全地選擇唯一ID(另請參見MySQL信息功能 ):

  • 創建一個表來保存序列計數器並對其進行初始化:

    mysql> CREATE TABLE序列(id INT NOT NULL);

    mysql>插入序列值(0);

  • 使用該表生成如下的序列號:

    mysql>更新序列SET id = LAST_INSERT_ID(id + 1);

    mysql> SELECT LAST_INSERT_ID();

兩種方法都是有效的。
Java方法與數據庫無關,對於您而言,切換數據庫或支持多個DB供應商可能更容易。

您的基本問題是,在存儲另一個對象之前,您需要數據庫中的信息來提供一個對象。

假設您將復合對象分成兩個較小的對象,即Place和Map。

如果必須有兩個緩沖區來存儲Place和Map,那么我會看到三種方式:

  1. 僅將Place放入存儲緩沖區。 當存儲了Place且已經從數據庫中讀取了PK時,僅將Map放置在另一個存儲緩沖區中。

  2. 將Place和Map放在自己的存儲緩沖區中。 即將存儲地圖時,請檢查其關聯的地方,以查看PK是否已生成。 如果有,則存儲地圖。 如果還沒有,請跳過該地圖並檢查下一張地圖。

  3. 將Place放入存儲緩沖區。 當它被存儲時,讀取PK,並立即也存儲地圖。 顯然,這不使用兩個存儲緩沖區。

查看其他對象如何存儲在您的應用程序中。 當然,它們在存儲在數據庫中之前不會生成自己的ID。 當然,您在擁有存儲它們所需的所有信息之前,不會嘗試將它們放入存儲緩沖區中。 因此,我建議的操作方法是選項1或3。

JDBC檢索生成的密鑰的標准接口是在語句上使用getGeneratedKeys()方法。 參見示例21.8。 Connector / J:使用 MySQL網站中的AUTO_INCREMENT列值

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM