Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Cách sử dụng khóa ngoại với PHP

Phân định cột / ràng buộc khóa ngoại

Giả sử bạn đang đề cập đến các ràng buộc khóa ngoại , câu trả lời ngắn gọn sẽ là bạn chỉ không sử dụng chúng .

Và đây là vấn đề dài:

Chúng tôi quen gọi cột là khóa ngoại sang các bảng khác. Đặc biệt là trong quá trình chuẩn hóa, các cụm từ như "user_purchase.i_id là một khóa ngoại cho các items bảng " sẽ rất phổ biến. Mặc dù đó là một cách hoàn toàn hợp lệ để mô tả mối quan hệ, nhưng nó có thể hơi mờ nhạt khi chúng ta đến giai đoạn triển khai.

Giả sử bạn đã tạo bảng của mình không có FOREIGN KEY mệnh đề:

CREATE TABLE user(
  id INT(11) NOT NULL AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL,
  password VARCHAR(20) NOT NULL,
  PRIMARY KEY (id)
);

CREATE TABLE items(
  i_id INT(11) NOT NULL AUTO_INCREMENT,
  name TINYTEXT NOT NULL,
  price DECIMAL(8,2) NOT NULL,
  PRIMARY KEY (i_id)
);

CREATE TABLE user_purchase(
  i_id INT(11) NOT NULL,
  name TINYTEXT NOT NULL,
  id INT(11) NOT NULL,
);

Lưu ý rằng, theo quan hệ, các cột khóa ngoại vẫn được triển khai . Có một cột tham chiếu đến user bảng (id ) và một cái khác tham chiếu đến items bảng (i_id ) - hãy đặt name cột sang một bên trong giây lát. Hãy xem xét các dữ liệu sau:

  user              user_purchase    items
| id  username |    | id  i_id |    | i_id  name            price |
| 23  john     |    | 55   10  |    |  10   chocolate bar    3.42 |
| 55  mary     |    | 70   10  |    |  33   mobile phone    82.11 |
| 70  fred     |    | 70   33  |    |  54   toothpaste       8.67 |
                    | 55   10  |    |  26   toy car          6.00 |
                    | 70   26  |

Mối quan hệ là ở đó. Nó được triển khai bằng user_purchase bảng lưu trữ thông tin về ai đã mua những gì . Nếu chúng tôi truy vấn cơ sở dữ liệu để tìm một báo cáo có liên quan, chúng tôi sẽ thực hiện:

select * from user_purchase p
join user u on (p.id=u.id)
join items i on (p.i_id=i.i_id)

Và đó là cách chúng tôi sử dụng quan hệ và cột khóa ngoại có liên quan.

Bây giờ, điều gì sẽ xảy ra nếu chúng ta làm:

insert into user_purchase (id,i_id) values (23,99)

Rõ ràng, đây là một mục nhập không hợp lệ. Mặc dù có người dùng id=23 , không có mục nào có i_id=99 . RDBMS sẽ cho phép điều đó xảy ra, bởi vì nó không biết cách nào tốt hơn . Chưa.

Đó là nơi mà khóa ngoại ràng buộc nhập cuộc. Bằng cách chỉ định FOREIGN KEY (i_id) REFERENCES items(i_id) trong user_purchase định nghĩa bảng, về cơ bản chúng tôi cung cấp cho RDBMS một quy tắc để tuân theo: các mục nhập có i_id các giá trị không có trong items.i_id cột không được chấp nhận . Nói cách khác, trong khi một cột khóa ngoại triển khai tham chiếu , một khóa ngoại ràng buộc thực thi tính toàn vẹn của tham chiếu .

Tuy nhiên, lưu ý rằng select ở trên sẽ không thay đổi, chỉ vì bạn đã xác định ràng buộc FK. Vì vậy, bạn không sử dụng các ràng buộc FK, RDBMS thực hiện, để bảo vệ dữ liệu của bạn.

Tiền thừa

Hãy tự hỏi bản thân:Tại sao bạn muốn điều đó? Nếu hai khóa ngoại phục vụ cùng một mục đích, thì việc dư thừa cuối cùng sẽ khiến bạn gặp rắc rối. Hãy xem xét các dữ liệu sau:

 user_purchase                   items
| id  i_id  name           |    | i_id  name            price |
| 55   10   chocolate bar  |    |  10   chocolate bar    3.42 |
| 70   10   chocolate bar  |    |  33   mobile phone    82.11 |
| 70   33   mobile phone   |    |  54   toothpaste       8.67 |
| 55   10   toothpaste     |    |  26   toy car          6.00 |
| 70   26   toy car        |

Chuyện gì với bức tranh vậy? Có phải người dùng 55 mua hai thanh sô cô la, hay một thanh sô cô la và kem đánh răng? Loại không rõ ràng này có thể dẫn đến rất nhiều nỗ lực để giữ cho dữ liệu được đồng bộ hóa, điều này sẽ không cần thiết nếu chúng ta chỉ giữ một trong các khóa ngoại. Trên thực tế, tại sao không bỏ name hoàn toàn là cột, vì nó được ngụ ý bởi quan hệ.

Tất nhiên, chúng tôi có thể giải quyết vấn đề này bằng cách triển khai khóa ngoại tổng hợp, bằng cách đặt PRIMARY KEY(i_id,name) cho các mục items bảng (hoặc xác định thêm một UNIQUE(i_id,name) lập chỉ mục, không thành vấn đề) và sau đó đặt FOREIGN KEY(i_id,name) REFERENCES items(i_id,name) . Bằng cách này, chỉ các cặp (i_id, name) tồn tại trong các mục items bảng sẽ hợp lệ cho user_purchases . Ngoài thực tế là bạn vẫn sẽ có một khóa ngoại , cách tiếp cận này hoàn toàn không cần thiết, miễn là i_id cột đã đủ để xác định một mục (không thể nói giống nhau cho name cột ...).

Tuy nhiên, không có quy tắc nào chống lại việc sử dụng nhiều khóa ngoại cho một bảng. Trên thực tế, có những trường hợp đòi hỏi một cách tiếp cận như vậy. Xem xét một person(id,name) bảng và parent(person,father,mother) một, với dữ liệu sau:

 person             parent
| id  name    |    | person  father  mother |
| 14  John    |    |   21      14      59   |
| 43  Jane    |    |   14      76      43   |
| 21  Mike    |
| 76  Frank   |
| 59  Mary    |

Rõ ràng, cả ba cột của parent bảng là các khóa ngoại đối với person . Không cho cùng một mối quan hệ , nhưng đối với ba cái khác nhau :Vì cha mẹ của một người cũng là một người, nên hai cột tương ứng phải tham chiếu đến cùng một bảng person làm. Tuy nhiên, lưu ý rằng ba trường không chỉ có thể nhưng cũng có phải giới thiệu person s trong cùng một parent hàng, vì không ai là cha mẹ của chính mình và cha của không ai cũng là mẹ của anh ta.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. TẠO BẢNG NẾU KHÔNG TỒN TẠI không thành công với bảng đã tồn tại

  2. Tìm kiếm một cột chứa dữ liệu CSV trong bảng MySQL để biết sự tồn tại của các giá trị đầu vào

  3. Cách nối các chuỗi trong MySQL với CONCAT ()

  4. Làm thế nào để hiển thị cơ sở dữ liệu MySQL trên một tập lệnh PHP?

  5. Giỏ hàng Thương mại Điện tử tốt nhất cho nhà phát triển Zend Framework