1

작은 피자 배달 웹 사이트에서 일하고 있는데 MySQL 테이블에 작은 문제가 발생했습니다. Mysql 외래 키가 상위 테이블의 전체 기본 키를 참조해야합니까?

는 I에 유래에서 이걸 발견 :

  • 두 테이블은 INNODB 엔진을 사용해야합니다 : https://stackoverflow.com/a/10322293/80907

    그것은 다음과 같은 언급하고있다.

  • "참조하는 테이블에서 외래 키 열이 동일한 순서의 첫 번째 열로 나열되어 인덱스가 있어야합니다."

을 첫 번째는 정말 문제가 있지만, 두 번째 규칙 아니다 내 머리를 긁적 인 곳이야.

피자를 주문할 수있는 웹 사이트이므로 사용자의 모든 데이터와 주문을 데이터베이스에 저장합니다.

는 여기에 내가 써하려고 해요 무엇의 스크린 샷입니다 :

enter image description here 그래서 내가 "사용자"테이블과 "주문"테이블을해야합니다. 사용자는 주문과 일대 다 관계를 유지해야합니다. 간단히 말해서, 주문은 그것을 만든 사용자에 의해 식별됩니다. 따라서 일대 다 방식으로 식별합니다.

"주문"테이블에 외래 키 (예 : "사용자 _ ID")가 있음을 의미합니다.

피자 테이블과 Orders 테이블 간의 다 대다 관계에 대한 테이블을 만들어야 할 때 문제가 발생합니다.

이 테이블을 "Order_Details"(자동으로 "Orders_has_Pizzas"라고하는 MySQL Workbench)라고 부르 자. "주문"과 "피자"를 모두 참조해야합니다.

이제 "주문"은 식별 관계에있는 사용자 테이블을 이미 참조하기 때문에 "주문"의 기본 키의 일부입니다.

과의 밖으로 다시 한 번 그 규칙하자 ". 외래 키 열이 동일한 순서의 첫 번째 열로 나열되어 인덱스가 있어야합니다, 참조하는 테이블에서"

이것이 의미하는 바는 전체 기본 키를 참조해야한다는 것입니다. "Order_Users_id"키를 삭제하면 데이터베이스를 만들 때 1005 오류가 발생합니다.

제 질문은 간단합니다.이 문제를 해결할 방법이 있습니까? 왜냐하면 지금 당장은 3 개의 다른 테이블에 언급 된 사용자 ID가 있습니다.

또는 제대로 이해하지 못하고 실제로 해당 데이터에 대해 다른 테이블을 쿼리하지 않아도됩니다.

편집 : 사용자가 식별하는 사용자와 주문 간의 관계에 대해 나와 의견이 맞지 않는 것 같습니다.

사용자의 ID를 모른 채 개별 주문을 식별하는 방법을 알 수 없습니다. 주문이 완료되면 누군가가 피자를 배달해야합니다. 즉, 피자를 배달 할 장소를 알아야합니다. 해당 데이터는 사용자 테이블에 있습니다.따라서 Users_id는 단일 주문의 ID의 일부입니다.

어쨌든 나는 그것을 볼 수 있습니다. 내가 틀렸다면 이유를 설명하십시오.

EDIT 2 : 데이터베이스 측면에서 "신원"개념을 명확히하기 위해 a_horse_with_no_name 덕분에 지금은 내 논리의 오류를 봅니다. 정보는 주석에서 찾을 수 있습니다.

+2

'Users_id'는 '주문'의 기본 키의 일부로해서는 안됩니다. – SLaks

+0

@SLaks : 그것은 식별 관계입니다. 이는 기본 키의 일부 여야 함을 의미합니다. 안 그래요? – KdgDev

+1

@slaks가 맞습니다. KdgDev는 주문을 어떻게 식별합니까? '주문 ID '에 의해, 그것은 아닌가요? 그러면 PK 식별자로'order id '만 필요합니다. – danihp

답변

2

원래의 질문에 대답하기 위해, 아니요, InnoDB 외래 키 제약 조건은 참조 된 테이블의 전체 기본 키를 참조 할 필요가 없습니다. 즉

, 이노에서 다음 작업을 모두 :

사실
mysql> ALTER TABLE Orders_has_Pizzas ADD FOREIGN KEY (Orders_id) 
    REFERENCES Orders (id); 
Query OK, 0 rows affected (0.63 sec) 

mysql> ALTER TABLE Orders_has_Pizzas ADD FOREIGN KEY (Orders_id,Orders_Users_id) 
    REFERENCES Orders (id, Users_id); 
Query OK, 0 rows affected (0.02 sec) 

가, InnoDB하지만이 기본 키의 일부가 아닌 경우에도, 외래 키가 어떤 인덱스 열을 참조 할 수 있습니다 :

mysql> CREATE TABLE Foo (fooid INT PRIMARY KEY, nonunique INT, KEY (nonunique)); 
Query OK, 0 rows affected (0.05 sec) 

mysql> CREATE TABLE Bar (barid INT PRIMARY KEY, foo_nonid INT, FOREIGN KEY (foo_nonid) 
    REFERENCES Foo(nonunique)); 
Query OK, 0 rows affected (0.06 sec) 

그러나 이것은 표준 SQL이 아니며 권장하지 않습니다. Bar의 한 행이 부모 테이블 Foo에서 둘 이상의 행을 참조 할 수 있음을 의미합니다. 즉, 외래 - 기본 키 관계에서이 둘 사이의 조인 (JOIN)이 예기치 않게 일종의 미니 데카르트 제품을 만들 수 있음을 의미합니다.

주문 테이블에서 복합 기본 키의 두 열에 중복이 포함될 수 있습니다. Orders_has_Pizzas의 주어진 행이 이론적으로 여러 주문을 참조 할 수 있음을 의미합니다.

식별 관계에 관한 질문에 대해서는 주문과 사용자를 구분하는 관계가 있음에 동의합니다. 즉, 참조 된 사용자가없는 순서가 존재하지 않는다.

그러나 고유 한 ID를 생성하기 위해 자동 증가 메커니즘을 사용하는 테이블에서는 여분의 열을 PK에 추가 할 필요가없는 것처럼 보입니다. 왜 사용자 ID가 포함 된 주문이 필요합니까? ID는 고유 한 것으로 각 행을 고유하게 주소 지정하기에 충분합니다.

이론은 우리에게 주문에 복합 기본 키를 생성하도록 안내하는 반면, 실용적인 선택이라고 말할 수 있습니다.

Orders_has_Pizzas와 같은 다 대다 테이블에서 더 명확 해집니다. 이 테이블에는 Orders와 Pizzas와의 식별 관계가 있습니다. 기본 키는 두 개의 외래 키로 구성됩니다. 하나는 Orders를 참조하고 다른 하나는 참조하는 피자입니다. 자동 증분 PK는 필요 없습니다.

어떤 사람들은 모든 테이블이 자동으로 생성 된 단일 컬럼의 기본 키를 가져야한다는 관례에 따라 다 대다 테이블에 불필요한 자동 증가 ID를 추가합니다. 그러나 이론적으로는 또는 실제 이유가 없습니다.

CREATE TABLE Orders_has_Pizzas (
    id INT AUTO_INCREMENT PRIMARY KEY, -- what is this column for? 
    Orders_id INT, 
    Orders_Users_id INT, 
    Pizzas_id INT, 
); 
+0

설명해 주셔서 감사합니다. 집에 가기 전에 강사에게 실을 보여 주었고 그녀는 데이터베이스의 측면에서 정체성 개념이 무엇인지에 대한 원래의 믿음은 이론적 인 수준에서 잘못되었다고 말했습니다. 여기에있는 의견을 읽은 후에, 필자는 필드가 고유 한 행을 가져와야하는지 관계가 식별하고 있다고 결론을 내린다. 따라서 사용자와 주문에는 식별 관계가 없습니다. Orders 테이블에서 고유 한 행을 얻으려면 user_id가 필요하지 않습니다. 그러나 user_id를 사용하면 거기에 기반한 JOIN을 수행 할 수있게되어 좋은 결과를 얻을 수 있습니다. 옳은? – KdgDev

+1

내가 해낸 책에서 자식 테이블의 FK가 자체 PK의 일부인 경우 식별 관계가되고 그렇지 않으면 그렇지 않습니다. 비록 그것이 원형 정의의 종류처럼 보일지라도 구현하려고 시도하는 논리적 인 관계 앞에 구현을 두는 것처럼 보일지라도. FK가 PK의 일부가 아닌 경우 (귀하와 같은 경우)가있을 ​​수 있지만 Orders 엔티티는 실제로 사용자 참조를 생략해서는 안됩니다. 이 경우 user_id를 NULL이 아니게 만들 수 있습니다. –

관련 문제