ER diyagramı, bir veritabanı tasarımının migration'a dönüşmeden önce kontrol edildiği yerdir. Tablo listesi neyin var olduğunu söyler. Diyagram ise tabloların birbirine nasıl bağlı olduğunu gösterir: hangi satırın hangisine ihtiyaç duyduğunu, neyin eksik olabileceğini ve çoka çok ilişkinin nerede saklandığını.
Bu rehber, küçük bir online mağaza veritabanını sade gereksinimlerden bitmiş bir varlık-ilişki diyagramına kadar tasarlıyor ve gösterimi yeri geldikçe açıklıyor. Mağaza yalnızca bir örnek; yöntem her şemada işe yarar.
Ne zaman ER diyagramına ihtiyacınız olur
Şemada bir avuç tablo varsa ve üzerinde tek bir ekip çalışıyorsa tablo listesi yeterlidir. Ekip dışındaki kişilerin veriyi anlaması gerektiğinde, migration yazmadan önce bir tasarımı gözden geçirdiğinizde ya da şema kimsenin aklında tutamayacağı kadar büyüdüğünde diyagramı çizin.
Yaygın iki gösterim vardır. Varlık-ilişki modelini tanıtan Peter Chen'in 1976 tarihli makalesinden gelen Chen gösterimi, varlıkları dikdörtgen, ilişkileri eşkenar dörtgen olarak çizer ve kavramsal modellemeye uygundur. Karga ayağı (crow's foot) gösterimi ise tabloları kutu olarak çizer ve kardinaliteyi çizgilerin uçlarına koyar. Genellikle 1976'da Gordon Everest'e atfedilir ve veritabanı tasarım araçlarının çoğunun kullandığı gösterimdir. Bu rehber karga ayağını kullanıyor.
Adım 1: Sade cümlelerle gereksinimler
Önce kuralları cümle olarak yazın. Her biri bir tabloya, bir sütuna ya da bir çizgiye dönüşür.
- Müşteri bir e-posta adresiyle kaydolur ve birden fazla adres kaydedebilir.
- Müşteri sipariş verir. Her sipariş, müşterinin adreslerinden birine gönderilir.
- Bir sipariş, her biri miktarı ve ödenen fiyatıyla birlikte bir veya daha fazla ürün içerir.
- Her ürün bir kategoriye aittir.
- Bir siparişin birden fazla ödeme denemesi olabilir ve çoğunda başarılı olan bir deneme bulunur.
Adım 2: Varlıklar ve anahtarlar
İsimler varlıklara dönüşür: müşteriler, adresler, siparişler, sipariş kalemleri, ürünler, kategoriler ve ödemeler. Her birine bir birincil anahtar verilir. Çoğu tabloda vekil anahtar (identity sütunu) kullanın; işin zaten bir doğal benzersiz anahtarı olduğu yerde onu da tanımlayın: müşterinin e-postası, ürünün SKU'su.
Sipariş kalemleri istisnadır. Bir sipariş kaleminin kendine ait bir kimliği yoktur; bir sipariş ile bir ürün arasındaki bağdır. Birincil anahtarı (order_id, product_id) çiftidir.
Adım 3: İlişkiler ve kardinalite
Her yabancı anahtar bir çizgidir. Uçlardaki semboller o tarafta kaç satır bulunabileceğini söyler:
| Çizgi ucu | Okunuşu | Mağazadan örnek |
|---|---|---|
| İki çizgi | Tam olarak bir | Her siparişi tam olarak bir müşteri verir |
| Daire ve çizgi | Sıfır veya bir | Eklerseniz, bir siparişin sıfır veya bir hediye mesajı olur |
| Çizgi ve karga ayağı | Bir veya çok | Bir siparişin bir veya çok sipariş kalemi olur |
| Daire ve karga ayağı | Sıfır veya çok | Bir müşterinin sıfır veya çok siparişi olur |
Bir ilişkiyi bir tablodan çizgi boyunca karşı uçtaki sembole doğru okuyun: "bir müşteri sıfır veya çok sipariş verir"; ters yönde ise "her siparişi tam olarak bir müşteri verir".
NOT NULL bir yabancı anahtar, başvurulan tarafta "tam olarak bir" anlamına gelir; NULL olabilen bir yabancı anahtar ise "sıfır veya bir" demektir. Diğer taraftaki "bir veya çok" bir iş kuralıdır, yabancı anahtarın zorladığı bir şey değildir; bu yüzden onu okuyucuların göreceği yere, diyagrama yazın.
Adım 4: Çoka çok ilişki
Siparişler ile ürünler arasında çoka çok ilişki vardır: bir sipariş çok sayıda ürün içerir, bir ürün de çok sayıda siparişte yer alır. İlişkisel veritabanları bunu ortada bir tabloyla modeller. Burada o tablo, yalnızca bağlantı kurmaktan daha iyi bir nedenle zaten var: order_items, ödeme anındaki miktarı ve birim fiyatı taşır. Bunlar iki taraftan birine tek başına değil, çiftin kendisine ait bilgilerdir.
Adım 5: Yazıya dökülmesi gereken kararlar
Bazı tercihler sütun listesinde görünmez ve kimse bilmediğinde hatalara yol açar:
- Fiyatın anlık kopyası.
order_items.unit_price, ödeme anındaki ürün fiyatını kopyalar. Bir fiyatı sonradan değiştirmek eski siparişleri değiştirmemelidir. - Adresler yerinde düzenlenmez. Bir sipariş bir adrese bağlandıktan sonra o satırı düzenlemek, geçmiş siparişlerin gönderildiği yeri yeniden yazmak olur. Düzenleme yeni bir adres satırı oluşturur.
- Ödemeler birer denemedir. Her deneme için durum bilgisiyle bir satır tutulur; böylece başarısız ve yeniden denenen ödemeler görünür kalır.
- Para
numericolarak tutulur. PostgreSQL dokümantasyonu, kesin olduğu için parasal tutarlardanumerickullanılmasını önerir.
Adım 6: DDL
PostgreSQL'deki iki merkezi tablo:
CREATE TABLE orders (
id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
customer_id bigint NOT NULL REFERENCES customers (id),
shipping_address_id bigint NOT NULL REFERENCES addresses (id),
status text NOT NULL DEFAULT 'pending'
CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled')),
currency char(3) NOT NULL,
total numeric(12,2) NOT NULL CHECK (total >= 0),
placed_at timestamptz NOT NULL DEFAULT now()
);
CREATE TABLE order_items (
order_id bigint NOT NULL REFERENCES orders (id) ON DELETE CASCADE,
product_id bigint NOT NULL REFERENCES products (id),
quantity integer NOT NULL CHECK (quantity > 0),
unit_price numeric(12,2) NOT NULL, -- copied from products.price at checkout
PRIMARY KEY (order_id, product_id)
);
CREATE INDEX ON orders (customer_id);
CREATE INDEX ON order_items (product_id);
PostgreSQL, yabancı anahtar sütunu için kendiliğinden indeks oluşturmaz; bu yüzden iki CREATE INDEX satırı, join'ler ve başvurulan tablolardaki silme işlemleri için önemlidir. order_items.order_id, indeksi bu sütunla başlayan birincil anahtar tarafından kapsanır. ON DELETE CASCADE, bir sipariş kaleminin siparişinden daha uzun yaşayamayacağını söyler.
Diyagram
Diyagram içeriği
- customers
- orders
- payments
- addresses
- order_items
- products
- categories
- belongs to
- placed by
- ships to
- pays for
- line of
- for
- in
Nasıl okunur:
- Müşterilerin (sol üstte) sıfır veya çok adresi olur ve sıfır veya çok sipariş verirler.
- Siparişler (ortada) tam olarak bir adrese gönderilir, bir veya çok sipariş kalemi içerir ve sıfır veya çok ödemesi olur.
- Sipariş kalemleri her siparişi ürünlere bağlar; her ürün tam olarak bir kategoriye aittir.
- Not, 5. adımdaki kararları etkiledikleri tabloların yanında tutar.
Okunaklı bir ER diyagramı nasıl çizilir
- İlişkileri fiillerle adlandırın. "verir", "gönderilir", "öder" gibi fiiller çizgileri cümleye dönüştürür.
- Anahtarları niteliklerde işaretleyin. PK ve FK işaretleri, bir çizginin hangi sütuna ait olduğunu bir bakışta gösterir.
- Tabloları alana göre gruplayın. Müşteriler ve adresler, sipariş ve ödemeler, katalog. Çizgiler kısa kalsın diye her grubu bir arada tutun.
- Gürültüyü dışarıda bırakın.
created_byveupdated_atgibi denetim sütunları, her tablodaki soft delete bayrakları ve teknik tablolar, anlayış katmadan satır ekler. - Çoka çok tabloyu çizin. Onu siparişler ile ürünler arasındaki doğrudan bir çizginin arkasına gizlemek, miktarı ve fiyatın anlık kopyasını da gizler.
- Şemanın gösteremediği iş kurallarını gösterin. Sipariş başına "bir veya çok" kalem ve "adresler düzenlenmez" kuralı, insanların bilmesi gereken kurallardır.
Diyagramı şemayla senkron tutun
Elle çizilmiş bir ER diyagramı bir sonraki migration'dan sonra eskir. Bunun yerine ilk taslağı şemadan üretin. Ücretsiz SQL'den ER diyagramına aracı CREATE TABLE ifadelerini ya da bütün bir pg_dump çıktısını okur; her tablo için PK, FK ve UK işaretli bir kart, her yabancı anahtar için de bir çizgi çizer. PostgreSQL, Prisma ve DBML için de araçlar var. Üretilen karga ayağı uçları sütunları izler: NOT NULL bir yabancı anahtar zorunlu, NULL olabilen bir yabancı anahtar isteğe bağlı olur. Sipariş başına "bir veya çok" kalem gibi SQL'in taşımadığı kuralları elle eklersiniz.
Archboard'da oluşturun
- Google ya da GitHub ile giriş yapın ve bir diyagram oluşturun.
- Şemadan başlamak için CREATE TABLE ifadelerini SQL'den ER diyagramına aracına yapıştırın ve Archboard’da aç seçeneğini seçin. Elle çizmek için her tabloya Varlık-İlişki paketinden bir Varlık ekleyin; her satıra bir nitelik yazın ve PK ile FK işaretlerini koyun.
- Her yabancı anahtarı başvurduğu tabloya bağlayın ve çizgi uçlarını karga ayağı işaretlerine ayarlayın: başvurulan tabloda tam olarak bir, yabancı anahtar tarafında sıfır veya çok, bir iş kuralının gerektirdiği yerde bir veya çok.
- Her çizgiyi "verir" ya da "gönderilir" gibi bir fiille etiketleyin.
- Tasarım kararları için Temel paketinden bir Markdown bloğu ekleyin.
Örnek 8 diyagram düğümü kullanıyor ve Free planın sınırları içinde kalıyor. Bir şemanın sistemin geri kalanına nasıl oturduğunu görmek için sistem tasarımı diyagramı örneğine bakın.
SSS
ER diyagramı ile veritabanı şeması diyagramı arasındaki fark nedir? Pratikte örtüşürler. ER diyagramı kavramsal olabilir ve tablolar oluşmadan önce varlıkları ve ilişkileri gösterir; şema diyagramı ise gerçek tabloları, sütunları ve anahtarları gösterir. Bu rehberdeki karga ayağı diyagramı ikisini birden yapıyor.
Her tablonun bir vekil anahtarı olmalı mı?
Çoğu tablo bundan fayda görür, çünkü doğal anahtarlar değişir. order_items gibi bağlantı tabloları ise birincil anahtar olarak çoğu zaman yabancı anahtar çiftini kullanır.
Çoka çok ilişkiyi nasıl gösteririm? Ortadaki tabloyla ve iki bire çok çizgiyle. Ortadaki tabloyu birleştirdiği iki tablonun adıyla değil, temsil ettiği şeyin adıyla adlandırın; örneğin sipariş kalemleri.
Her sütunu çizmeli miyim? Anahtarları ve tasarımı açıklayan sütunları çizin. Diyagram onlarla ilgili değilse denetim ve teknik sütunları dışarıda bırakın.
Chen mi, karga ayağı mı? Tablolarla düşünmeyen kişilerle yapılan kavramsal tartışmalarda Chen, veritabanına dönüşecek her şeyde karga ayağı.