Diyelim ki sunduğum 4 tür hizmetim var (sık sık değişme olasılığı yoktur):
- Test yapmak
- tasarlamak
- Programlama
- Diğer
Her birinin yukarıdaki kategorilerden birine giren 60-80 gerçek hizmetim olduğunu varsayalım. Örneğin, 'hizmet', "A tekniği kullanarak Test Programı" olabilir ve "Test" türündedir.
Onları bir veritabanına kodlamak istiyorum. Birkaç seçenek buldum:
Seçenek 0:
VARCHAR
Hizmet türünü doğrudan bir dize olarak kodlamak için doğrudan kullanın
Seçenek 1:
Veritabanını kullan enum
. Ancak, enum kötüdür
Seçenek 2:
iki tablo kullanın:
service_line_item (id, service_type_id INT, description VARCHAR);
service_type (id, service_type VARCHAR);
Referans bütünlüğünün tadını bile çıkarabilirim:
ALTER service_line_item
ADD FOREIGN KEY (service_type_id) REFERENCES service_type (id);
Kulağa hoş geliyor, evet?
Ama yine de bir şeyleri kodlamam ve tamsayılarla uğraşmam gerekiyor, yani tabloyu doldururken. Veya tabloyu doldururken veya doldururken ayrıntılı programlama veya DB yapıları oluşturmalıyım. Yani, doğrudan veritabanıyla ilgilenirken veya programlama tarafında yeni nesne yönelimli varlıklar yaratırken ve onları doğru çalıştırdığımdan emin olduğumda JOIN'lar.
Seçenek 3:
Kullanmayın enum
, iki tablo kullanmayın, sadece bir tamsayı sütunu kullanın
service_line_item (
id,
service_type INT, -- use 0, 1, 2, 3 (for service types)
description VARCHAR
);
Bu, şeylerin kod tarafında daha fazla ek yük gerektiren bir 'sahte enum' gibi, yani bunu bilmek {2 == 'Programming'}
ve onunla başa çıkmak gibi .
Soru:
Şu anda , kavramlar altında yönlendirilen Seçenek 2'yi kullanarak uyguladım.
- enum kullanmayın (seçenek 1)
- veritabanını elektronik tablo olarak kullanmaktan kaçının (seçenek 0)
Fakat bunun programlama ve bilişsel yükü açısından benim için zararlı göründüğünü hissetmeye yardım edemem - iki masanın farkında olmalıyım ve iki masayla başa çıkmalıyım.
'Daha az boşa giden bir yol' için bakıyorum Option 3
. BT daha hafiftir ve temelde aynı kod yapıları için çalışır (küçük değişikliklerle ancak karmaşıklık ve yapı temelde aynıdır, ancak tek bir tablo ile)
Bence ideal olarak her zaman boşa gitmiyor ve her iki seçenek için de iyi durumlar var, fakat Seçenek 2'nin ne zaman ve Seçenek 3'ü ne zaman kullanması gerektiği konusunda iyi bir rehber var mı?
Sadece iki tip olduğunda (ikili)
Bu soruya biraz daha fazla eklemek için ... aynı mekanda, servis satır öğesine uygulanabilecek "Standart" veya "İstisna" Hizmeti'nin ikili seçeneğine sahibim. Seçenek 3 kullanarak bunu kodladım .
Sadece {"Standard", "Exception"} değerlerini tutmak için yeni bir tablo oluşturmamayı seçtim. Bu yüzden benim sütunum {0, 1} tutar ve sütun ismim çağrılır exception
ve kodum bir çeviri yapıyor {0, 1} => {STANDARD, EXCEPTION}
(programlama dilinde sabit olarak kodladım)
Şimdiye kadar bu şekilde ya da değil ..... (seçenek 2 veya seçenek 3'ü beğenmedim). Seçenek 2'yi 3'ten daha üstün buluyorum, ancak daha fazla ek yüke sahipken, yine de 2 ve 3'ten hangisini kullanırsam kullansam da tamsayı olarak kodlama olaylarından kaçamıyorum.
ORM
Bazı bağlamları eklemek için, cevapları okuduktan sonra - bir ORM kullanmaya yeni başlamıştım (yakın zamanda), benim durumumda Doktrin 2. Ek Notlar aracılığıyla DB şemasını tanımladıktan sonra veritabanını doldurmak istedim. Veri setimin tamamı nispeten küçük olduğundan, nasıl çalıştığını görmek için programlama yapıları kullanmayı denemek istedim.
Önce service_type
s'yi, ardından service_line_item
s'yi, gerçek bir elektronik tablonun var olan bir listesi olduğu için doldurdum . Bu nedenle, 'standart / istisna' ve 'Test' gibi şeylerin hepsi e-tablodaki dizelerdir ve bunları DB'ye kaydetmeden önce uygun türlere kodlanmaları gerekir.
Bu SO cevabını buldum: doctrine2'de ENUM yerine ne kullanıyorsunuz? DB'nin enum yapısını kullanmamak, bir INT
alan kullanmak ve programlama dilinin 'const' yapısını kullanarak türlerini kodlamak için önerilmektedir .
Ancak yukarıdaki SO sorusunda belirtildiği gibi, tamsayıları doğrudan kullanmaktan kaçınabilir ve dil yapılarını - sabitleri - tanımlandıktan sonra kullanabilirim ....
Ama yine de .... nasıl çevirdiğiniz önemli değil, string
bir tür olarak başlıyorsam, bir ORM kullanırken bile ilk önce uygun bir türe dönüştürmem gerekir.
Öyleyse $str = 'Testing';
, yine de, bunun gibi bir şeyi yapan bir yerde bir bloğa ihtiyacım var:
switch($str):
{
case 'Testing': $type = MyEntity::TESTING; break;
case 'Other': $type = MyEntity::OTHER; break;
}
İşin iyi yanı, tam sayılar / sihirli sayılarla uğraşmamaktır [bunun yerine, kodlanmış sabit miktarlarla uğraşmaktır], ama kötü olan şey, bu dönüşüm aşaması olmadan veritabanına girip çıkan şeyleri otomatik olarak sihirli bir şekilde çekememenizdir. bilgi.
Kısacası, "hala bir şeyleri kodlamak ve tamsayılarla uğraşmak zorunda olmak" gibi şeyler söyleyerek demek istedim. (Şimdi, Ocramius'un yorumundan sonra, tamsayılarla doğrudan uğraşmak zorunda kalmayacağım, ancak isimlendirilmiş sabitler ve gerektiğinde sabitlerden bazı dönüşümlere / dönüşümlerle uğraşmak zorunda kalmayacağım).