PostgreSQL에서 다 대다 관계를 구현하는 방법은 무엇입니까?
제목은 자명하다고 생각합니다. 다 대다 관계를 만들기 위해 PostgreSQL에서 테이블 구조를 어떻게 생성합니까?
내 예 :
Product(name, price);
Bill(name, date, Products);
SQL DDL (데이터 정의 언어) 문은 다음과 같습니다.
CREATE TABLE product (
product_id serial PRIMARY KEY -- implicit primary key constraint
, product text NOT NULL
, price numeric NOT NULL DEFAULT 0
);
CREATE TABLE bill (
bill_id serial PRIMARY KEY
, bill text NOT NULL
, billdate date NOT NULL DEFAULT CURRENT_DATE
);
CREATE TABLE bill_product (
bill_id int REFERENCES bill (bill_id) ON UPDATE CASCADE ON DELETE CASCADE
, product_id int REFERENCES product (product_id) ON UPDATE CASCADE
, amount numeric NOT NULL DEFAULT 1
, CONSTRAINT bill_product_pkey PRIMARY KEY (bill_id, product_id) -- explicit pk
);
몇 가지 조정을했습니다.
N : m 관계는 일반적으로 별도의 테이블로 구현한다 -
bill_product이 경우.serial열을 대리 기본 키로 추가했습니다 . 제품 이름이 거의 고유하지 않기 때문에 강력히 추천합니다. 또한 고유성을 적용하고 외래 키에서 열을 참조하는integer것은text또는로 저장된 문자열보다 4 바이트를 사용하는 것이 훨씬 저렴varchar합니다.
Postgres 10 이상에서는 대신IDENTITY열을 고려하십시오 . 세부:같은 기본 데이터 유형의 이름을 사용하지 마십시오
date으로 식별자 . 이것이 가능하지만 잘못된 스타일이며 혼란스러운 오류 및 오류 메시지로 이어집니다. 사용 법률, 소문자, 인용 부호로 둘러싸이지 않은 식별자 . 예약어를 사용하지 말고 가능하면 큰 따옴표로 묶인 대소 문자 구분 식별자를 사용하지 마십시오 .name좋은 이름이 아닙니다. 나는 이름이 바뀐name테이블의 열product수product. 더 나은 명명 규칙 입니다. 그렇지 않으면 관계형 데이터베이스에서 많은 작업을 수행하는 쿼리에서 두 개의 테이블을 조인 할 때 이름이 여러 열로 지정name되고 열 별칭을 사용하여 혼란을 정리해야합니다. 도움이되지 않습니다. 또 다른 널리 퍼진 안티 패턴은id열 이름과 같습니다.
의 이름이 무엇인지 잘 모르겠습니다bill. 어쩌면bill_id수 있습니다 이름 이 경우이다.price입력 된대로 정확하게 분수를 저장 하는 데이터 유형 입니다 (부동 소수점 유형 대신 임의 정밀도 유형). 정수만 다루면 . 예를 들어 가격을 Cents로 저장할 수 있습니다.numericintegeramount("Products"귀하의 질문에)이 연결 테이블로 전환bill_product및 유형입니다numeric뿐만 아니라. 다시 말하지만,integer정수만 다루면.당신은 볼 외래 키 에를
bill_product? 변경 사항을 계단식으로 만들기 위해 둘 다 만들었습니다 (ON UPDATE CASCADE) :product_id또는bill_id변경해야하는 경우 변경 사항이의 모든 종속 항목에 계단식으로 적용bill_product되고 중단되지 않습니다.
나는 또한 사용ON DELETE CASCADE을 위해bill_id: 당신이 법안을 삭제하면 세부 사항도 함께 삭제됩니다.
그렇지 않은 제품 : 청구서에 사용 된 제품을 삭제하고 싶지 않습니다. 이 작업을 시도하면 Postgres에서 오류가 발생합니다.product대신 사용되지 않는 행을 표시 하기 위해 에 다른 열을 추가 합니다.All columns in this basic example end up to be
NOT NULL, soNULLvalues are not allowed. (Yes, all columns - columns used in a primary key are definedUNIQUE NOT NULLautomatically.) That's becauseNULLvalues wouldn't make sense in any of the columns. It makes a beginner's life easier. But you won't get away so easily, you need to understandNULLhandling anyway. Additional columns might allowNULLvalues, functions and joins can introduceNULLvalues in queries etc.Read the chapter on
CREATE TABLEin the manual.Primary keys are implemented with a unique index on the key columns, that makes queries with conditions on the PK column(s) fast. However, the sequence of key columns is relevant in multicolumn keys. Since the PK on
bill_productis on(bill_id, product_id)in my example, you may want to add another index on justproduct_idor(product_id, bill_id)if you have queries looking for given aproduct_idand nobill_id. Details:Read the chapter on indexes in the manual.
'Nice programing' 카테고리의 다른 글
| 두 필드로 Javascript 정렬 배열 (0) | 2020.11.12 |
|---|---|
| Xcode 4로 내 앱을 현지화하는 방법은 무엇입니까? (0) | 2020.11.12 |
| 변경 불가능한 비트 맵 충돌 오류 (0) | 2020.11.12 |
| C #에서 모든 공백을 % 20으로 어떻게 바꾸나요? (0) | 2020.11.12 |
| 추상화와 캡슐화는 어떻게 다릅니 까? (0) | 2020.11.12 |