MySQL'de birden çok sütun için benzersiz kısıtlamayı nasıl belirleyebilirim?


865

Bir masam var:

table votes (
    id,
    user,
    email,
    address,
    primary key(id),
);

Şimdi sütunları kullanıcı, e-posta, adres (birlikte) yapmak istiyorum .

Bunu MySql'de nasıl yapabilirim?

Tabii ki örnek sadece ... bir örnektir. Lütfen anlambilim konusunda endişelenmeyin.

Yanıtlar:


1436
ALTER TABLE `votes` ADD UNIQUE `unique_index`(`user`, `email`, `address`);

31
Bu INSERT deyimlerinin ON DUPLICATE KEY yan tümcesi ile düzgün çalışır mı? Yani, başka bir satırın kullanıcı / e-posta / adres değerleri ile çakışan bir satır eklemek çalışıyordum, INSERT bunun yerine ON DUPLICATE KEY yan tümcesi tarafından belirtilen eylemleri yapar mı?
clizzin

6
Bu şekilde üçün kombinasyonu benzersiz olur mu? Yoksa her üç sütun da benzersiz mi?
Gary Lindahl

95
MySQL çalışma tezgahını kullanan kişiler için: Dizinler sekmesine gidin ve türünüz olarak BENZERSİZ'i seçin. Dizininize bir ad verin ve "Dizin Sütunları" bölümünün altındaki uygun sütunları kontrol edin
Pakman

10
Benim gibi, başka biri arama motorlarından bulduysa ... ve Clizzin'in ON DUPLICATE KEY'in kompozit bir anahtarla çalışıp çalışmayacağı sorusunu cevaplaması için - kesinlikle sözdiziminde bazı küçük ayarlamalar gerektirecektir. bkz. stackoverflow.com/questions/9537710/…
Joe

2
NULL değeriyle bile çalışmasını sağlamak. NULL değerine sahip iki aynı satır eklersek, bu işe yaramıyor ...
Wasim A.

237

Bir MySQL tablo var:

CREATE TABLE `content_html` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_box_elements` int(11) DEFAULT NULL,
  `id_router` int(11) DEFAULT NULL,
  `content` mediumtext COLLATE utf8_czech_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_box_elements` (`id_box_elements`,`id_router`)
);

ve BENZERSİZ ANAHTAR beklendiği gibi çalışır, id_box_elements ve id_router çoklu NULL satırlarına izin verir.

MySQL 5.1.42 çalıştırıyorum, bu yüzden muhtemelen yukarıda tartışılan konuda bazı güncelleme vardı. Neyse ki çalışıyor ve umarım bu şekilde kalacaktır.


34
Bu cevabı, jonstjohn'un yukarıdaki cevabı mevcut bir tabloyu nasıl güncelleyeceğinizi anlatan benzersiz bir indeks ile nasıl yeni bir tablo oluşturulacağını gösterdiği gibi işaretlemek istedim. Aynı şeyi yaparlar, ancak yeni bir tablo oluşturmanıza veya mevcut bir tabloyu güncellemenize bağlıdır. :)
GazB

3
tüm backquotes ile ne, bir amaca hizmet ediyorlar mı?
puk

8
Bu geri tırnakları otomatik olarak ekleyen Yönetici'den (www.adminer.org) çıktıdır, bu nedenle sütun adı olarak kullanılan mysql anahtar kelimelerinin çarpışmasıyla ilgili bir sorun yoktur.
Frodik

50

MySQL NULL'a benzersiz bir değer olarak davranır ve en azından şu anda çok sütunlu dizinlerde geçici olarak çalışacak bir mantık yoksa, satırda NULL değeriniz varsa, çok sütunlu benzersiz dizinler MySQL'de çalışmaz. Evet davranış çılgınca, çünkü çok sütunlu indekslerin bir çok meşru uygulamasını sınırlıyor, ama ne olduğu ... Şimdilik, MySQL'de "düzeltilmeyecek" ile damgalanmış bir hata bug-track ...


11
İki açıklama noktası: 1) bu davranış için geçerli değildir ENGINE BDBve 2) bu belgelenmiş davranıştır, ancak IMHO, ne kadar şaşırtıcı / nahoş olabileceği göz önüne alındığında yeterince açık bir şekilde belgelenmemiştir. Tartışma için MySQL hatası 25544 bugs.mysql.com/bug.php?id=25544 adresine bakın .
pilc

2
NULL başkanları için teşekkürler, yaşadığım sorunu ele aldı ... Sanırım karma bir sağlama toplamı ile gideceğim
Daniel Doezema

7
Bu bir cevap değil. Orijinal soruya bir yorum olmalı.
Sınırlı Kefaret

Resmi dokümanlar şunları söylüyor: MySQL 5.1'den itibaren BDB'nin artık desteklenmediğini unutmayın.
George

2
Çok iyi bilgi, ama cevap değil. Sadece çevresel olarak soru ile ilgilidir.
billynoah

23

Bunu denedin mi?

UNIQUE KEY `thekey` (`user`,`email`,`address`)

Ne Erick benim için sadece iyi işler söyledi: UNIQUE KEY thekey` ( user, email, address) `. MYSQL 5.5.24 sürümünü kullanıyorum Bunu PHPMYADMIN'de bile kullanıyorsanız ayarlayabilirsiniz. PMA'nın 3.5.1 sürümünü kullanıyorum.
WQC

MySql 5.6 ile denedim. İlk denemeden itibaren çalışır. Teşekkürler Erick!
Lawrence

11

Bu, mysql sürüm 5.5.32 için çalışır

ALTER TABLE  `tablename` ADD UNIQUE (`column1` ,`column2`);

1
Sütun adında tek tırnak işaretleri olmadan çalışıyor gibi görünüyor.
Pratik Singhal

7

MySql 5 veya üstü bu şekilde davranır (yeni test ettim):

  • null olabilecek sütunları içeren benzersiz kısıtlamalar tanımlayabilirsiniz. Diyelim ki A boş ve B olmayan benzersiz bir kısıtlama (A, B)
  • böyle bir kısıtlamayı değerlendirirken istediğiniz kadar (A, null) olabilirsiniz (aynı A değeri!)
  • sadece bir (A, boş B değil) çiftiniz olabilir

Örnek: PRODUCT_NAME, PRODUCT_VERSION 'bardak', boş 'bardak', boş 'şarap', 1

Şimdi tekrar ('şarap' 1) eklemeye çalışırsanız, bir sınırlama ihlali bildirecektir.


açıkladığın için teşekkürler.
Eşsizim

6

PhpMyAdmin ile çok sütunlu benzersiz dizinler ekleyebilirsiniz . (Sürüm 4.0.4'te test ettim)

Hedef tablonuzun yapı sayfasına gidin . Sütunlardan birine benzersiz bir dizin ekleyin. Eklediğiniz benzersiz dizini görmek için yapı sayfasının altındaki Dizinler listesini genişletin . Düzenle simgesini tıklayın ve aşağıdaki iletişim kutusunda bu benzersiz dizine ek sütunlar ekleyebilirsiniz.


3

Bunu şöyle yaparım:

CREATE UNIQUE INDEX index_name ON TableName (Column1, Column2, Column3);

Eşsiz index_nameolan için benim sözleşmem TableName_Column1_Column2_Column3_uindex.


2

Benzersiz dizin eklemek için aşağıdakiler gereklidir:

1) tablo_adı
2) dizin_adı
3) dizin eklemek istediğiniz sütunlar

ALTER TABLE  `tablename` 
ADD UNIQUE index-name
(`column1` ,`column2`,`column3`,...,`columnN`);

Sizin durumunuzda aşağıdaki gibi benzersiz bir dizin oluşturabiliriz:

ALTER TABLE `votes`ADD 
UNIQUE <votesuniqueindex>;(`user` ,`email`,`address`);

1

Gelecekte kopyalarını önlemek istiyorsanız. İd2 diyelim başka bir sütun oluşturun.

UPDATE tablename SET id2 = id;

Şimdi benzersiz olanı iki sütuna ekleyin:

alter table tablename add unique index(columnname, id2);

1

MySQL'de tablo oluşturuyorsanız, aşağıdakileri kullanın:

create table package_template_mapping (
mapping_id  int(10) not null auto_increment  ,
template_id int(10) NOT NULL ,
package_id  int(10) NOT NULL ,
remark      varchar(100),
primary key (mapping_id) ,
UNIQUE KEY template_fun_id (template_id , package_id)
);

0

İlk önce mevcut kopyalardan kurtulun

delete a from votes as a, votes as b where a.id < b.id 
and a.user <=> b.user and a.email <=> b.email 
and a.address <=> b.address;

Ardından benzersiz kısıtlamayı ekleyin

ALTER TABLE votes ADD UNIQUE unique_index(user, email, address);

Kısıtlamayı aşağıdakilerle doğrulayın:

SHOW CREATE TABLE votes;

Kullanıcı, e-posta, adresin herhangi birinde boş değer varsa benzersiz kabul edileceğini unutmayın.


0

PostgreSQL için ... Benim için dizinle çalışmadı; bana bir hata verdi, bu yüzden bunu yaptım:

alter table table_name
add unique(column_name_1,column_name_2);

PostgreSQL benzersiz dizine kendi adını verdi. Eğer değiştirilmesi gerekiyorsa, tablo seçeneklerinde dizin adını değiştirebilirsiniz sanırım ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.