Apakah membuat bidang unik membuatnya diindeks?

10

Jika saya membuat uniquebatasan pada bidang, apakah saya juga perlu membuat indeks pada bidang tersebut untuk mendapatkan waktu memasukkan yang dapat diukur? Atau apakah ini dilakukan untuk saya (bahkan jika indeks yang digunakannya tidak dapat diakses publik?)

Secara khusus, saya bekerja dengan Apache Derby untuk pembuatan prototipe, meskipun saya mungkin akan memindahkannya ke MySQL dalam waktu dekat. Saya juga berharap mungkin ada sesuatu dalam standar SQL yang mengatakan sesuatu tentang ini.

Saya tidak akan pernah perlu mencari berdasarkan bidang ini, jadi saya lebih suka tidak membuat indeks yang tidak berguna. Tapi saya lebih suka memiliki indeks yang tidak berguna daripada memiliki O(n)waktu memasukkan.

corsiKa
sumber
2
Dari apa yang saya tahu kendala unik diterapkan di belakang menggunakan indeks unik. Anda dapat melihat beberapa pendapat mengenai situasi ini dalam pertanyaan ini: kapan harus menggunakan batasan unik alih-alih indeks unik?
Marian
@Marian terima kasih atas tautannya. Itu sangat mendalam.
corsiKa

Jawaban:

2

--EDIT--

Jawaban asli saya (di bawah) mungkin tidak berguna bagi Anda sama sekali karena tidak menjawab pertanyaan uniquekendala. Seperti yang orang lain katakan, kendala ini biasanya diimplementasikan dengan indeks unik tersirat. Dalam kasus khusus ini mungkin tidak benar (misalnya disable novalidateuntuk Oracle).

Pertanyaannya bisa: Apakah mungkin untuk menegakkan keunikan tanpa indeks? Secara umum jawabannya adalah tidak meskipun dalam beberapa kasus Indeks Clustered akan berarti bahwa indeks dan tabel adalah objek yang sama.

--END EDIT--

Anda berkata "Saya lebih suka memiliki indeks yang tidak berguna daripada memiliki waktu memasukkan O (n).", Tetapi secara umum database tidak memiliki waktu memasukkan O (n). Ada dua hal yang perlu dipertimbangkan:

  1. Tabel normal dengan atau tanpa indeks:

    Baris baru dibuang di bagian atas tumpukan. RDBMS mungkin hanya terlihat pada 1 blok, jadi bukan hanya O (1) tetapi O yang sangat kecil (1).

    Jika tabel memiliki indeks, penunjuk ke baris akan ditambahkan ke masing-masing. Ini biasanya merupakan operasi O (log (n)).

  2. Tabel dengan beberapa jenis pengelompokan yang terjadi, misalnya Indeks Terorganisir Tabel atau cluster untuk Oracle, atau Indeks Clustered untuk SQL Server dan lainnya:

    Baris baru dimasukkan ke blok tertentu, yang dapat menyebabkan blok terbelah atau meluap, tetapi apa pun yang terjadi itu masih O (log (n)) atau lebih baik , disebabkan oleh b-tree atau struktur serupa yang digunakan untuk menemukan blok.

Jack mengatakan coba topanswers.xyz
sumber
Tetapi keunikan tanpa indeks akan O(n)seperti Anda harus memeriksa seluruh tabel. Itulah yang saya coba hindari.
corsiKa
Ini memang jawaban terbaik untuk pertanyaan ini !!! +1
RolandoMySQLDBA
@ Trik - ya, saya salah paham pada awalnya. Indeks adalah harga yang Anda bayar untuk kendala keunikan yang saya khawatirkan. Bisakah Anda menggunakan Indeks Clustered dalam kasus Anda?
Jack bilang coba topanswers.xyz
1
@JackPDougless Saya bisa menggunakan "indeks" standar dan mendapatkan waktu O(lg n)memasukkan. Itu bukan masalah. Pertanyaan saya adalah apakah sistem, mengetahui bahwa Anda memerlukan indeks untuk mendapatkan waktu memasukkan yang layak, buat indeks untuk saya.
corsiKa
2

PRIMARY KEY> = UNIQUE> = INDEX == KEY

Data InnoDB dipesan oleh PK. MyISAM PK bertindak sama dengan UNIK.

INSERT harus menambahkan "baris" ke masing-masing dan setiap indeks (apa pun jenisnya) yang Anda miliki. Ini membutuhkan waktu. (Biasanya tidak cukup waktu untuk masalah.) Indeks semua disimpan dalam format BTree. Blok MyISAM BTree adalah 1KB; InnoDB menggunakan 16KB.

Memasukkan ke dalam InnoDB memperbarui PK dan data secara bersamaan.

Memasukkan ke dalam MyISAM biasanya "menambahkan" data ke .MYD. Secara terpisah, ini menambahkan baris ke PK (jika ada).

INSERT harus terlebih dahulu memverifikasi bahwa tidak ada kunci duplikat untuk kunci PRIMARY atau UNIK. Ini dilakukan dengan menggunakan indeks. Dan, karenanya, mengapa KONSTRA KUNCI UNIK dan ASING benar-benar membangun indeks. Ini adalah O (logN), tetapi biasanya CPU, bukan I / O, karena jika caching efisien.

Rick James
sumber
Apakah Anda memiliki kutipan dalam spesifikasi InnoDB yang menyatakan UNIQUEkendala akan membuat indeks tanpa pengguna menentukan satu yang akan dibuat?
corsiKa
Hmmm ... Tidak, hanya pengalaman bertahun-tahun.
Rick James
Dan inilah cara untuk mengujinya ... BUAT tabel tanpa indeks sekunder; do SHOW TABLE STATUS - Index_length akan menjadi 0. Kemudian tambahkan indeks UNIQUE; TABEL STATUS sekarang akan menunjukkan sesuatu. (Mungkin harus memasukkan jumlah data yang tidak sepele dalam tabel.)
Rick James
1

Untuk menjawab pertanyaan dengan huruf tebal: Ya, membuat bidang yang unik tidak mengindeksnya seperti kunci utama s. Bahkan, saya telah membahas ini dalam pertanyaan lain sehubungan dengan Kunci Utama Memiliki Nama Sendiri untuk membedakannya dari Kunci Unik (Kandidat) lainnya .

Sedangkan untuk kendala, indeks dibuat untuk Anda sehingga paradigma kendala diatur. Anda harus dapat menghapus indeks duplikat, bahkan kunci UNIK, selama kendala yang Anda buat tidak merujuk kunci UNIK lainnya yang Anda buat secara terpisah dari paradigma kendala.

Anda mungkin tidak pernah harus mencari bidang ini, tetapi MySQL tentu harus sebagai jalurnya untuk menentukan validitas kunci dan menentukan bagaimana cara menjalankan ON DELETE CASCADE dan ON UPDATE CASCADE.

Indeks UNIK hanya menjamin keunikan tupel (lajang, pasangan, kembar tiga, ..., n-tupel, dll) di setiap baris dalam tabel.

Adalah kebijaksanaan Anda untuk menghapus indeks duplikat tersebut, asalkan Anda tidak melanggar paradigma kendala yang Anda inginkan.

RolandoMySQLDBA
sumber
1
Ini tidak menjawab pertanyaan saya. Pertanyaan saya terkait dengan waktu penyisipan. Jika Anda memiliki batasan unik, sistem harus memastikan keunikan bidang sebelum memasukkan - jika tidak ada indeks pada bidang, itu harus mencari seluruh tabel ( O(n)). Jika ada indeks, pencarian akan jauh lebih cepat (mungkin O(lg n)). Itu masalah saya. Saya menyadari mekanisme integritas referensial, saya hanya peduli (untuk tujuan pertanyaan ini) tentang kinerja.
corsiKa