วิธีทำการกำหนดเวอร์ชันแถวใน MySQL ในขณะที่ยังคงรักษาความสมบูรณ์ของการอ้างอิงคีย์ต่างประเทศ

ลูกค้าของฉันมีรูปแบบธุรกิจที่เปลี่ยนแปลงแบบไดนามิก พวกเขาขายผลิตภัณฑ์ตามอัตราแลกเปลี่ยน USD รายวัน ซึ่งหมายความว่าราคาของผลิตภัณฑ์เปลี่ยนแปลงในแต่ละวัน และลูกค้ายังคงต้องการรักษาประวัติ (ราคา, date_sold) ของผลิตภัณฑ์ที่ขาย (ข้อมูลนี้ถูกบันทึกไว้ในตารางคำสั่งซื้อ)

วิธีเดียวที่ฉันสามารถนึกถึงการใช้โซลูชันสำหรับลูกค้าของฉันได้คือการใช้การกำหนดเวอร์ชันแถว (พวกเขากำลังใช้ MySQL เป็นเซิร์ฟเวอร์ฐานข้อมูล)

นี่คือสคีมาปัจจุบัน (เช่นเดียวกับต้นแบบ) ที่ฉันต้องการนำไปใช้ในขณะที่รักษาความสมบูรณ์ของการอ้างอิง แต่เมื่อฉันสร้างตารางคำสั่งซื้อ ฉันได้รับข้อผิดพลาดดังนี้:

ERROR 1005 (HY000): Can't create table 'mydb.orders' (errno: 150)

ด้วยการออกแบบสคีมา:

create table products (
 id int not null auto_increment,                                           
 prod_id int not null,
 name varchar(200) NOT NULL,
 price decimal(8,2) NOT NULL default 0,
 is_active boolean default 0,
 deleted boolean default 0,
 create_date timestamp NOT NULL default current_timestamp,
 end_date timestamp NOT NULL default '2030-01-01 00:00:00',
 primary key(id)                                                   
)engine=innodb;   

create table orders (
  id int not null auto_increment,
  prod_id int not null,
  foreign key(prod_id) references products(prod_id),
  date_sold timestamp NOT NULL default current_timestamp,
  primary key(id)
)engine=innodb;

เหตุใดฉันจึงไม่สามารถสร้างคีย์ต่างประเทศให้กับตารางผลิตภัณฑ์ได้ ผมทำอะไรผิดหรือเปล่า?

คำแนะนำใด ๆ ที่ชื่นชมมาก

ขอบคุณ!

แจ้งเพื่อทราบ

การตั้งค่าเซิร์ฟเวอร์ฐานข้อมูล

  • เพอร์โคนา MySQL 5.5.27
  • ฉันจัดการการกำหนดเวอร์ชันใน db_layer ของฉันโดยใช้การประทับเวลาและแฟล็กบูลีน

อัปเดต : ฉันต้องสร้างดัชนีในคอลัมน์ orders(prod_id) คำจำกัดความสคีมาที่ถูกต้องสำหรับตาราง orders คือ:

 create table orders (
      id int not null auto_increment,
      prod_id int not null,
      index product_id(prod_id),
      foreign key(prod_id) references products(prod_id),
      date_sold timestamp NOT NULL default current_timestamp,
      primary key(id)
    )engine=innodb;

person Chesneycar    schedule 21.09.2012    source แหล่งที่มา
comment
โปรดทราบว่าคุณกำลังจัดเก็บสำเนาข้อมูลผลิตภัณฑ์อื่นๆ ทั้งหมด (ชื่อ ฯลฯ) เพียงเพื่อเก็บไว้เป็นสำเนาราคา แยกราคาออกเป็นตารางอื่น (พร้อมวันที่) หรือใช้ทริกเกอร์เพื่อเขียนราคาเก่าลงในตารางประวัติเมื่อมีคนอัปเดต product.price   -  person Alain Collins    schedule 21.09.2012


คำตอบ (1)


จำเป็นต้องมีดัชนีในคอลัมน์ที่คุณกำลังอ้างอิง ลองสร้างดัชนีบน prod_id ในตารางผลิตภัณฑ์ จากนั้นลองสร้างคีย์นอกของคุณ

นอกจากนี้ ทำไมไม่เพียงแค่เพิ่มคอลัมน์ราคาลงในตารางคำสั่งซื้อและคัดลอกราคาผลิตภัณฑ์ปัจจุบัน ณ เวลาที่ขาย ซึ่งจะให้ข้อมูลประวัติของคุณและคุณไม่จำเป็นต้องรักษาบันทึกผลิตภัณฑ์เวอร์ชันต่างๆ

person bobwienholt    schedule 21.09.2012
comment
ขอบคุณที่แนะนำครับ จะลองทำดูครับ - person Chesneycar; 21.09.2012
comment
มันได้ผล! ขอบคุณสำหรับคำตอบ. ฉันอัปเดตคำถามเพื่อแสดงคำจำกัดความสคีมาตารางที่ถูกต้องของตารางคำสั่งซื้อ - person Chesneycar; 21.09.2012
comment
ฉันยอมรับว่าการคัดลอกราคาปัจจุบันง่ายกว่า แต่ไม่แน่ใจว่าจะได้ผลดีสำหรับการตรวจสอบหรือไม่ เนื่องจากคุณ (@Bosvark) กำลังสูญเสียประวัติที่แท้จริงของการเปลี่ยนแปลงราคา และดังที่ Alain กล่าวไว้ คุณสามารถจัดเก็บเฉพาะราคาตามเวอร์ชันแทนข้อมูลผลิตภัณฑ์ทั้งหมดได้ (IANAL/F/A - ไม่ใช่ทนายความ/การเงิน/นักบัญชี) - person aneroid; 05.10.2012