Bagaimana cara menentukan batasan unik untuk beberapa kolom di MySQL?

865

Saya punya meja:

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

Sekarang saya ingin membuat kolom pengguna, email, alamat unik (bersama).

Bagaimana saya melakukan ini di MySql?

Tentu saja contohnya hanyalah ... contoh. Jadi tolong jangan khawatir tentang semantiknya.

Niyaz
sumber

Jawaban:

1436
ALTER TABLE `votes` ADD UNIQUE `unique_index`(`user`, `email`, `address`);
Johnstjohn
sumber
31
Apakah ini berfungsi dengan baik pada klausa ON DUPLICATE KEY dari pernyataan INSERT? Yaitu, jika saya mencoba menyisipkan baris yang bertentangan dengan nilai pengguna / email / alamat baris lain, akankah INSERT melakukan tindakan yang ditentukan oleh klausa ON DUPLICATE KEY sebagai gantinya?
clizzin
6
Dengan begitu kombinasi tiga akan menjadi unik? Atau ketiga kolom individual itu unik?
Gary Lindahl
95
Bagi mereka yang menggunakan MySQL workbench: buka tab Indexes dan pilih UNIQUE sebagai tipe Anda. Beri nama indeks Anda dan periksa kolom yang sesuai di bawah bagian "Kolom Indeks"
Pakman
10
Seperti saya, jika ada orang lain yang menemukan ini dari mesin pencari ... dan untuk menjawab pertanyaan Clizzin tentang apakah ON DUPLICATE KEY akan bekerja dengan kunci komposit - itu benar-benar akan, namun itu akan memerlukan beberapa penyesuaian kecil pada sintaksis. lihat stackoverflow.com/questions/9537710/…
Joe
2
bagaimana membuatnya bekerja bahkan dengan nilai NULL. Jika kita memasukkan Dua baris yang sama dengan nilai NULL, ini tidak berfungsi ...
Wasim A.
237

Saya punya tabel MySQL:

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`)
);

dan KUNCI UNIK berfungsi seperti yang diharapkan, ini memungkinkan beberapa baris NULL id_box_elements dan id_router.

Saya menjalankan MySQL 5.1.42, jadi mungkin ada beberapa pembaruan pada masalah yang dibahas di atas. Untungnya itu berhasil dan mudah-mudahan akan tetap seperti itu.

Frodik
sumber
34
Saya ingin menandai jawaban ini karena ini menunjukkan kepada Anda bagaimana membuat tabel baru dengan indeks unik di mana sebagai jawaban jonstjohn di atas memberitahu Anda cara memperbarui tabel yang ada. Mereka melakukan hal yang sama meskipun hanya tergantung pada apakah Anda membuat tabel baru atau memperbarui yang sudah ada. :)
GazB
3
ada apa dengan semua backquote, apakah mereka melayani beberapa tujuan?
puk
8
Ini adalah keluaran dari Adminer (www.adminer.org) yang menyisipkan backquote ini secara otomatis, jadi tidak ada masalah dengan bertabrakan kata kunci mysql yang digunakan sebagai nama kolom.
Frodik
50

Indeks unik multi kolom tidak berfungsi di MySQL jika Anda memiliki nilai NULL berturut-turut karena MySQL memperlakukan NULL sebagai nilai unik dan setidaknya saat ini tidak memiliki logika untuk mengatasinya dalam indeks multi-kolom. Ya perilakunya gila, karena membatasi banyak aplikasi yang sah dari indeks multi-kolom, tetapi itu adalah apa ... Sampai sekarang, itu adalah bug yang telah dicap dengan "tidak akan memperbaiki" pada MySQL bug-track ...

niksoft
sumber
11
Dua poin klarifikasi: 1) perilaku ini tidak berlaku untuk ENGINE BDB, dan, 2) ini perilaku yang didokumentasikan , meskipun, IMHO, tidak cukup terdokumentasi mengingat betapa mengejutkan / tidak menyenangkannya itu. Lihat bug MySQL 25544 bugs.mysql.com/bug.php?id=25544 untuk diskusi.
pilcrow
2
Terima kasih untuk NULL yang mengepalai, membahas masalah yang saya alami ... Saya pikir saya akan pergi dengan hash checksum
Daniel Doezema
7
Ini bukan jawaban. Itu harus menjadi komentar untuk pertanyaan awal.
Penebusan Terbatas
Dokumen resmi mengatakan: Perhatikan bahwa, pada MySQL 5.1, BDB tidak lagi didukung.
George D.
2
Informasi yang sangat bagus, tetapi bukan jawaban. Hanya terkait perifer dengan pertanyaan.
billynoah
23

Sudahkah Anda mencoba ini?

UNIQUE KEY `thekey` (`user`,`email`,`address`)
Erick
sumber
Apa Erick mengatakan karya-karya baik-baik saja untuk saya: UNIQUE KEY thekey` ( user, email, address) `. Saya menggunakan MYSQL versi 5.5.24 Anda dapat mengatur ini bahkan di PHPMYADMIN jika Anda menggunakannya. Saya menggunakan versi 3.5.1 dari PMA.
WQC
Sudah mencobanya dengan MySql 5.6. Bekerja dari percobaan pertama. Erick terima kasih!
Lawrence
11

Ini berfungsi untuk versi mysql 5.5.32

ALTER TABLE  `tablename` ADD UNIQUE (`column1` ,`column2`);
Rizon
sumber
1
Tampaknya berfungsi tanpa tanda kutip tunggal pada nama kolom.
Pratik Singhal
7

MySql 5 atau lebih berperilaku seperti ini (saya baru saja menguji):

  • Anda dapat mendefinisikan batasan unik yang melibatkan kolom yang dapat dibatalkan. Katakanlah Anda mendefinisikan batasan unik (A, B) di mana A tidak dapat dibatalkan tetapi B adalah
  • ketika mengevaluasi batasan seperti itu, Anda dapat memiliki (A, null) sebanyak yang Anda inginkan (nilai A yang sama!)
  • Anda hanya dapat memiliki satu (A, bukan null B) pasangan

Contoh: PRODUCT_NAME, PRODUCT_VERSION 'gelas', nol 'gelas', nol 'anggur', 1

Sekarang jika Anda mencoba memasukkan ('wine' 1) lagi itu akan melaporkan pelanggaran kendala Semoga ini bisa membantu

Cristian Botiza
sumber
terima kasih sudah menjelaskan. Saya memiliki keunikan (A, B, C) dan saya tidak tahu mengapa itu mengizinkan kombinasi null dengan opsi non-null yang sama
Alexandru Topal
6

Anda dapat menambahkan indeks unik beberapa kolom melalui phpMyAdmin . (Saya menguji dalam versi 4.0.4)

Arahkan ke halaman struktur untuk tabel target Anda. Tambahkan indeks unik ke salah satu kolom. Buka daftar Indeks di bagian bawah halaman struktur untuk melihat indeks unik yang baru saja Anda tambahkan. Klik ikon edit, dan dalam dialog berikut Anda dapat menambahkan kolom tambahan ke indeks unik itu.

Vince K
sumber
3

Saya melakukannya seperti ini:

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

Konvensi saya untuk yang unik index_nameadalah TableName_Column1_Column2_Column3_uindex.

Sam Malayek
sumber
2

Untuk menambahkan indeks unik, diperlukan:

1) table_name
2) index_name
3) kolom di mana Anda ingin menambahkan indeks

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

Dalam kasus Anda, kami dapat membuat indeks unik sebagai berikut:

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

Jika Anda ingin menghindari duplikat di masa depan. Buat kolom lain say id2.

UPDATE tablename SET id2 = id;

Sekarang tambahkan unik pada dua kolom:

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

Jika Anda membuat tabel di mysql kemudian gunakan yang berikut:

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)
);
Devendra Singraul
sumber
0

Pertama-tama singkirkan duplikat yang ada

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;

Kemudian tambahkan batasan unik

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

Verifikasi kendala dengan

SHOW CREATE TABLE votes;

Perhatikan bahwa pengguna, email, alamat akan dianggap unik jika salah satu dari mereka memiliki nilai nol di dalamnya.

Ganesh Krishnan
sumber
0

Untuk PostgreSQL ... Tidak berfungsi untuk saya dengan indeks; itu memberi saya kesalahan, jadi saya melakukan ini:

alter table table_name
add unique(column_name_1,column_name_2);

PostgreSQL memberi indeks unik namanya sendiri. Saya kira Anda dapat mengubah nama indeks dalam opsi untuk tabel, jika perlu diubah ...

bugthefifth
sumber