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_productbu 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 textveya olarak depolanan bir dizeden daha ucuzdur varchar.
Gibi temel veri tiplerinin isimlerini kullanmayın dateolarak 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) productolarak 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.productproduct_namebillbill_id
pricetaşı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_productve tiptedir numericde. Yine, integeryalnı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_idveya bill_iddeğişmesi gerekiyorsa, değişiklik tüm bağlı girdilere basamaklanır bill_productve hiçbir şey bozulmaz. Bunlar, kendilerine ait önemi olmayan referanslardır.
Ayrıca şunun ON DELETE CASCADEiç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 productyerine 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 NULLnedenle, NULLdeğerler izin verilmez. (Evet, tüm sütunlar - birincil anahtar sütunlar UNIQUE NOT NULLotomatik 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 NULLidare etmeyi anlamalısın . Ek sütunlar NULLdeğerlere, işlevlere ve birleştirmelere izin verebilir , NULLsorgulara vb. Değerler ekleyebilir .
CREATE TABLEKı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_productolduğu için (bill_id, product_id), sadece üzerine başka bir dizin eklemek isteyebilirsiniz product_idveya (product_id, bill_id)verilen product_idve 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.