2014-09-15 79 views
7

Basit kategoriler tablosum var. Kategori ana kategoriye (par_cat sütun) sahip olabilir veya ana kategori ise ve aynı üst kategori ile aynı ad veya URL'ye sahip 2 veya daha fazla kategori olmamalıdır. Bu tablo içinTek sütunta benzersiz (çoklu sütunlar) ve null

Kodu:

CREATE TABLE IF NOT EXISTS `categories` (
`id` int(10) unsigned NOT NULL, 
    `par_cat` int(10) unsigned DEFAULT NULL, 
    `lang` varchar(2) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'pl', 
    `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL, 
    `url` varchar(120) COLLATE utf8_unicode_ci NOT NULL, 
    `active` tinyint(3) unsigned NOT NULL DEFAULT '1', 
    `accepted` tinyint(3) unsigned NOT NULL DEFAULT '1', 
    `priority` int(10) unsigned NOT NULL DEFAULT '1000', 
    `entries` int(10) unsigned NOT NULL DEFAULT '0', 
    `created_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', 
    `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=3 ; 



ALTER TABLE `categories` 
    ADD PRIMARY KEY (`id`), 
    ADD UNIQUE KEY `categories_name_par_cat_unique` (`name`,`par_cat`), 
    ADD UNIQUE KEY `categories_url_par_cat_unique` (`url`,`par_cat`), 
    ADD KEY `categories_par_cat_foreign` (`par_cat`); 


ALTER TABLE `categories` 
    MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3; 

ALTER TABLE `categories`ADD CONSTRAINT `categories_par_cat_foreign` 
    FOREIGN KEY (`par_cat`) REFERENCES `categories` (`id`); 

Sorun benzersiz anahtarları olsa bile çalışmıyor olmasıdır. par_catnull olarak ayarlanmış ve aynı ad ve URL'ye sahip veritabanı 2 kategorisine girmeye çalışırsam, bu 2 kategori veritabanına sorun olmadan eklenebilir (ve yapmamalılar). Ancak diğer par_cat kategorilerini seçersem (örneğin, 1 kimliğine sahip kategori varsayarak), sadece ilk kayıt eklenir (ve bu istenen davranış).

Soru - Bu dava nasıl ele alınır?

EŞSİZ indeks endeksi tüm değerler farklı olmalıdır böyle bir sınırlama oluşturur: Bunu okudum. Varolan bir satıra uyan anahtar değeriyle yeni bir satır eklemeye çalışırsanız bir hata oluşur. Bu kısıtlama, BDB depolama altyapısı dışında NULL değerlerine uygulanmaz. Diğer motorlar için, UNIQUE dizini, NULL içerebilen sütunlar için birden fazla NULL değerine izin verir. UNIQUE dizinindeki bir sütun için bir önek değeri belirtirseniz, sütun değerleri önek içinde benzersiz olmalıdır. Ben o böyle değil beklenen birden çok sütun üzerinde benzersiz var ancak eğer

(sadece par_cat, name boş olabilir ve url null olamaz). par_cat, aynı tablonun id referansı olduğundan, ancak bazı kategoriler ana kategoriye sahip olmadığından null değerlerine izin vermelidir.

+0

[10-şeyler-in-mysql-bu-beklenmedik çalışma] (http://explainextended.com/2010/11/03/10-things-in-mysql-that-wont-work -as-beklenen /) –

+0

[Bu yanıt] (http://stackoverflow.com/a/429827/3630826) sahip olduğunuz sorunu açıklayabilir. Par_cat'i null olarak değiştirmemenizi öner, root için 0 gibi bir minimun kimliği ayarla. Ve otomatik artış kategori kimliği 1. –

+0

@JaugarChang Ama ben de par_cat' için yabancı anahtar kısıtlaması var, bu yüzden 0 –

cevap

16

Bu, SQL standardı tarafından tanımlanan şekilde çalışır. NULL bilinmeyen anlamına gelir. Eğer par_cat = NULL ve name = 'X' olmak üzere iki kaydınız varsa, iki NULL değeri aynı değeri taşımaz. Böylece benzersiz anahtar kısıtlamalarını ihlal etmiyorlar. (N1, null hala aynı değer anlamına gelebilir, ancak bu kuralın uygulanması benzersiz indeksler ve nullable alanları ile çalışmayı neredeyse imkansız kılabilirdi çünkü NULL, 1, 2 veya başka bir değer anlamına gelebilir. Benim görüşüme göre yaptıkları gibi tanımlamak için iyi yaptım.)

MySQL, ISNULL(par_cat,-1), name üzerinde bir dizininiz olabileceği işlevsel dizinleri desteklemediğinden, tek seçeneğiniz, 0 veya -1 ile par_cat NOT NULL sütununu yapmaktır. veya kısıtlamaların çalışmasını istiyorsanız "ebeveyn yok" için.

+2

Tamam, anlıyorum. Ama eğer ben NULL yapmazsam, yabancı anahtar kısıtı 'yabancı anahtar kısıtlaması' 'par_cat' için 0' par_cat' eklemek mümkün olmayacaktır (par_cat') REFERANSLAR 'kategorileri' (' id'); '.Bu yüzden 2 kısıtlama arasında seçim yapmak zorunda olduğum anlamına mı geliyor - ya yabancı anahtar kullan (null ile) ve benzersiz değil ya da benzersiz kullanmayın ama par_cat'ta yabancı anahtarı kaldırın, çünkü bu 2 kısıtlama birlikte çalışmayacak? –

+4

Ya da kimlik 0 ile bir kukla kayıt kategorilere. –

+1

Tamam, ama önce yabancı anahtar oluşturmadan önce koymam gerekiyor, aksi halde veritabanına eklenemedi, değil mi? Bu durumda yaygın uygulama nedir? Böyle bir 0 kaydı (önerdiğiniz gibi) koyun veya yabancı anahtar veya benzersiz anahtar kullanmayın? '0 kaydını kullanıyorum 'durumunda, eğer her şeyi DB'den almak istiyorsam, her zaman' 0 kaydını ' –

İlgili konular