Başlığın kendi kendini açıklayıcı olduğuna inanıyorum. PostgreSQL'de çoktan çoğa bir ilişki kurmak için tablo yapısını nasıl oluşturursunuz?
Örneğim:
Product(name, price);
Bill(name, date, Products);
Başlığın kendi kendini açıklayıcı olduğuna inanıyorum. PostgreSQL'de çoktan çoğa bir ilişki kurmak için tablo yapısını nasıl oluşturursunuz?
Örneğim:
Product(name, price);
Bill(name, date, Products);
Yanıtlar:
SQL DDL (veri tanımlama dili) ifadeleri şöyle görünebilir:
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
);
Birkaç düzenleme yaptım:
N: m ilişki normal olarak ayrı bir tablo tarafından uygulanan - bill_product
bu durumda.
Vekil birincil anahtarlarserial
olarak sütunlar ekledim . Postgres 10 veya sonraki sürümlerde bunun yerine bir sütun düşünün . Görmek:IDENTITY
Bunu şiddetle tavsiye ediyorum, çünkü bir ürünün adı pek benzersiz değil (iyi bir "doğal anahtar" değil). Ayrıca, benzersizliği zorlamak ve sütuna yabancı anahtarlarda başvurmak, genellikle 4 bayt integer
(veya hatta 8 bayt bigint
) ile text
veya olarak depolanan bir dizeden daha ucuzdur varchar
.
Gibi temel veri tiplerinin isimlerini kullanmayın date
olarak tanımlayıcılar . Bu mümkün olsa da, kötü bir tarzdır ve kafa karıştırıcı hatalara ve hata mesajlarına yol açar. Kullanım hukuki, küçük harf, tırnaksız tanımlayıcılar . Asla ayrılmış sözcükler kullanmayın ve mümkünse çift tırnaklı karışık büyük / küçük harf tanımlayıcılardan kaçının.
"isim" iyi bir isim değil. Tablonun sütununu ( veya benzeri) product
olarak yeniden adlandırdım . Bu daha iyi bir adlandırma kuralı . Aksi takdirde, ilişkisel bir veritabanında çok yaptığınız bir sorguda birkaç tabloyu birleştirdiğinizde, sonunda "ad" adlı birden çok sütunla karşılaşırsınız ve karışıklığı gidermek için sütun takma adlarını kullanmanız gerekir. Bu yardımcı olmuyor. Diğer bir yaygın anti-model, sütun adı olarak sadece "id" olacaktır.
A'nın adının ne olacağından emin değilim . bu durumda muhtemelen yeterli olacaktır.product
product_name
bill
bill_id
price
taşımaktadır veri türü numeric
fraksiyonel numaralarını saklamak için tam olarak girilmesi (yerine kayan nokta türü keyfi hassas türü). Yalnızca tam sayılarla ilgileniyorsanız, bunu yapın integer
. Örneğin, fiyatları Sent olarak kaydedebilirsiniz .
amount
( "Products"
Sorunuzu) bağlayan tabloya gider bill_product
ve tiptedir numeric
de. Yine, integer
yalnızca tam sayılarla ilgileniyorsanız.
Görüyorsunuz yabancı anahtarları içinde bill_product
? Ben kaskad değişikliklerine hem oluşturuldu: ON UPDATE CASCADE
. Bir product_id
veya bill_id
değişmesi gerekiyorsa, değişiklik tüm bağlı girdilere basamaklanır bill_product
ve hiçbir şey bozulmaz. Bunlar, kendilerine ait önemi olmayan referanslardır.
Ayrıca şunun ON DELETE CASCADE
için de kullandım bill_id
: Bir fatura silinirse, detayları onunla birlikte ölür.
Ürünler için geçerli değil: Faturada kullanılan bir ürünü silmek istemezsiniz. Bunu denerseniz Postgres bir hata atar. Bunun product
yerine eski satırları işaretlemek için başka bir sütun eklersiniz ("yazılımla silme").
Bu temel örnek uç up Tüm sütunlar olmak NOT NULL
nedenle, NULL
değerler izin verilmez. (Evet, tüm sütunlar - birincil anahtar sütunlar UNIQUE NOT NULL
otomatik olarak tanımlanır .) Bunun nedeni NULL
, sütunların hiçbirinde değerlerin anlamlı olmamasıdır. Yeni başlayanların hayatını kolaylaştırır. Ama bu kadar kolay kurtulamayacaksın, yine de NULL
idare etmeyi anlamalısın . Ek sütunlar NULL
değerlere, işlevlere ve birleştirmelere izin verebilir , NULL
sorgulara vb. Değerler ekleyebilir .
CREATE TABLE
Kılavuzdaki bölümü okuyun .
Birincil anahtarlar , PK sütun (lar) ındaki koşullarla sorguları hızlı hale getiren, anahtar sütunlarında benzersiz bir dizin ile uygulanır . Ancak, anahtar sütunlarının sırası çok sütunlu anahtarlarla ilgilidir. Benim örneğimde PK açık bill_product
olduğu için (bill_id, product_id)
, sadece üzerine başka bir dizin eklemek isteyebilirsiniz product_id
veya (product_id, bill_id)
verilen product_id
ve hayır arayan sorgularınız varsa bill_id
. Görmek:
Kılavuzdaki dizinlerle ilgili bölümü okuyun .
bill_product
? Normalde görünüyor gibi olmalıdır: CREATE INDEX idx_bill_product_id ON booked_rates(bill_id, product_id)
. Bu doğru mu?
bill
. Eklenen öğe başına miktara ihtiyacımız var bill_product
.