Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

SQL:Membuat tabel relasi dengan 2 peningkatan otomatis yang berbeda

Konsep

Anda telah salah memahami beberapa konsep dasar, dan kesulitan yang diakibatkannya. Kita harus mengatasi konsepnya terlebih dahulu, bukan masalah seperti yang Anda rasakan, dan akibatnya, masalah Anda akan hilang.

ID yang ditambahkan secara otomatis, yang tentu saja merupakan kunci utama.

Tidak, mereka bukan. Itu adalah kesalahpahaman umum. Dan masalah dijamin akan terjadi.

Sebuah ID field tidak boleh menjadi Kunci Utama dalam pengertian bahasa Inggris atau teknis atau Relasional.

  • Tentu, dalam SQL, Anda dapat mendeklarasikan apa saja bidang menjadi PRIMARY KEY , tetapi itu tidak secara ajaib mengubahnya menjadi Kunci Utama dalam pengertian bahasa Inggris, teknis, atau Relasional. Anda dapat memberi nama chihuahua "Rottweiller", tetapi itu tidak mengubahnya menjadi Rottweiller, ia tetap menjadi chihuahua. Seperti bahasa apapun, SQL hanya menjalankan perintah yang Anda berikan, tidak mengerti PRIMARY KEY berarti sesuatu yang Relasional, itu hanya memukul indeks unik pada kolom (atau bidang).

  • Masalahnya adalah, karena Anda telah menyatakan ID menjadi PRIMARY KEY , Anda berpikir sebagai Kunci Utama, dan Anda dapat mengharapkan bahwa ia memiliki beberapa kualitas dari Kunci Utama. Kecuali keunikan nilai ID , tidak memberikan manfaat. Itu tidak memiliki kualitas dari Kunci Utama, atau Kunci Relasional apa pun dalam hal ini. Ini bukan Kunci dalam pengertian bahasa Inggris, teknis, atau Relasional. Dengan mendeklarasikan non-kunci sebagai kunci, Anda hanya akan membingungkan diri sendiri, dan Anda akan menemukan bahwa ada sesuatu yang sangat salah hanya ketika pengguna mengeluh tentang duplikat dalam tabel.

Tabel relasional harus memiliki baris keunikan

PRIMARY KEY pada ID bidang tidak menyediakan baris keunikan. Oleh karena itu, ini bukan tabel Relasional yang berisi baris, dan jika bukan itu, maka itu adalah file yang berisi catatan. Itu tidak memiliki integritas, atau kekuatan (pada tahap ini Anda hanya akan mengetahui kekuatan gabungan), atau kecepatan, yang dimiliki tabel dalam database Relasional.

Jalankan kode ini (MS SQL 2008) dan buktikan sendiri. Harap jangan hanya membaca ini dan memahaminya, lalu lanjutkan membaca sisa Jawaban ini, kode ini harus dijalankan sebelum membaca lebih lanjut . Ini memiliki nilai kuratif.

    CREATE TABLE dumb_file (
        id         INT      NOT NULL  IDENTITY  PRIMARY KEY,
        name_first CHAR(30) NOT NULL,
        name_last  CHAR(30) NOT NULL
        )

    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds
    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds, but not intended
    INSERT dumb_file VALUES ( "Mickey", "Mouse" )  -- succeeds, but not intended

    SELECT * FROM dumb_file

Perhatikan bahwa Anda memiliki baris duplikat . Tabel relasional harus memiliki baris yang unik . Bukti lebih lanjut bahwa Anda tidak memiliki tabel relasional, atau salah satu kualitas tabel tersebut.

Perhatikan bahwa dalam laporan Anda, satu-satunya hal yang unik adalah ID bidang, yang tidak dipedulikan pengguna, tidak dilihat pengguna, karena itu bukan data, itu adalah omong kosong tambahan yang beberapa "guru" yang sangat bodoh menyuruh Anda untuk memasukkan setiap file. Anda memiliki catatan keunikan tapi bukan baris keunikan.

Dalam hal data (data nyata dikurangi penambahan asing), data name_last dan name_first bisa ada tanpa ID bidang. Seseorang memiliki nama depan dan nama belakang tanpa tanda pengenal di dahinya.

Hal kedua yang Anda gunakan yang membingungkan Anda adalah AUTOINCREMENT. Jika Anda menerapkan sistem pengarsipan catatan tanpa kemampuan Relasional, tentu saja, ini sangat membantu, Anda tidak perlu mengkodekan kenaikan saat memasukkan catatan. Tetapi jika Anda menerapkan Basis Data Relasional, itu tidak ada gunanya sama sekali, karena Anda tidak akan pernah menggunakannya. Ada banyak fitur dalam SQL yang kebanyakan orang tidak pernah gunakan.

Tindakan Perbaikan

Jadi bagaimana Anda memutakhirkan, meninggikan, dumb_file yang penuh dengan baris duplikat ke tabel Relasional, untuk mendapatkan beberapa kualitas dan manfaat dari tabel Relasional? Ada tiga langkah untuk ini.

  1. Anda perlu memahami Kunci

    • Dan karena kami telah berkembang dari file ISAM tahun 1970-an, ke Model Relasional , Anda perlu memahami Kunci Relasional . Artinya, jika Anda ingin mendapatkan manfaat (integritas, kekuatan, kecepatan) dari Database Relasional.

    Dr E F Cood, dalam RM hisnya , menyatakan bahwa:

    kunci dibuat dari data

    dan

    baris dalam tabel harus unik

    "Kunci" Anda tidak dibuat dari data. Ini adalah beberapa tambahan, parasit non-data, yang disebabkan oleh Anda terinfeksi penyakit "guru" Anda. Kenalilah seperti itu, dan biarkan diri Anda memiliki kapasitas mental penuh yang Tuhan berikan kepada Anda (perhatikan bahwa saya tidak meminta Anda untuk berpikir dalam istilah yang terisolasi atau terfragmentasi atau abstrak, semua elemen dalam database harus terintegrasi satu sama lain). Buat kunci asli dari data, dan hanya dari data. Dalam hal ini, hanya ada satu Kunci yang mungkin:(name_last, name_first).

  2. Coba kode ini , deklarasikan batasan unik pada data:

         CREATE TABLE dumb_table (
            id         INT      NOT NULL  IDENTITY  PRIMARY KEY,
            name_first CHAR(30) NOT NULL,
            name_last  CHAR(30) NOT NULL
    
            CONSTRAINT UK 
                UNIQUE ( name_last, name_first )
            )
    
        INSERT dumb_table VALUES ( "Mickey", "Mouse" )  -- succeeds
        INSERT dumb_table VALUES ( "Mickey", "Mouse" )  -- fails, as intended
        INSERT dumb_table VALUES ( "Minnie", "Mouse" )  -- succeeds
    
        SELECT * FROM dumb_table
    

    Sekarang kita memiliki keunikan baris . Itulah urutan yang terjadi pada kebanyakan orang:mereka membuat file yang memungkinkan penipuan; mereka tidak tahu mengapa penipuan muncul di drop-down; pengguna berteriak; mereka mengubah file dan menambahkan indeks untuk mencegah penipuan; mereka pergi ke perbaikan bug berikutnya. (Mereka mungkin melakukannya dengan benar atau tidak, itu cerita yang berbeda.)

  3. Tingkat kedua. Untuk pemikiran orang-orang yang berpikir di luar fix-its. Karena kita sekarang memiliki keunikan baris, apa yang di Surga adalah tujuan dari ID lapangan, mengapa kita bahkan memilikinya ??? Oh, karena chihuahua itu bernama Rotty dan kami takut untuk menyentuhnya.

    Deklarasi bahwa itu adalah PRIMARY KEY salah, tetapi tetap ada, menyebabkan kebingungan dan harapan yang salah. Satu-satunya Kunci asli yang ada, adalah (name_last, name_fist), dan ini adalah Kunci Alternatif saat ini.

    Oleh karena itu ID lapangan benar-benar berlebihan; dan begitu juga indeks yang mendukungnya; dan begitu juga dengan AUTOINCREMENT; begitu juga dengan pernyataan palsu bahwa itu adalah PRIMARY KEY; dan harapan apa pun yang Anda miliki tentangnya adalah salah.

    Oleh karena itu hapus ID yang berlebihan bidang. Coba kode ini :

        CREATE TABLE honest_table (
            name_first CHAR(30) NOT NULL,
            name_last  CHAR(30) NOT NULL
    
            CONSTRAINT PK 
            PRIMARY KEY ( name_last, name_first )
            )
    
        INSERT honest_table VALUES ( "Mickey", "Mouse" )  -- succeeds
        INSERT honest_table VALUES ( "Mickey", "Mouse" )  -- fails, as intended
        INSERT honest_table VALUES ( "Minnie", "Mouse" )  -- succeeds
    
        SELECT * FROM honest_table
    

    Berfungsi dengan baik, berfungsi sebagaimana dimaksud, tanpa bidang dan indeks asing.

    Harap ingat ini, dan lakukan dengan benar, setiap saat.

Guru Palsu

Di akhir zaman ini, seperti yang disarankan, kita akan memiliki banyak dari mereka. Perhatikan baik-baik, "guru" yang menyebarkan ID kolom, berdasarkan bukti rinci dalam posting ini, sama sekali tidak memahami Model Relasional atau Basis Data Relasional. Terutama mereka yang menulis buku tentang itu.

Terbukti, mereka terjebak dalam teknologi ISAM pra-1970. Hanya itu yang mereka pahami, dan hanya itu yang bisa mereka ajarkan. Mereka menggunakan wadah database SQL, untuk kemudahan Akses, pemulihan, pencadangan, dll, tetapi kontennya murni Sistem Pengarsipan Catatan tanpa Integritas Relasional, Kekuatan, atau kecepatan. AFAIC, ini adalah penipuan serius.

Selain ID bidang, tentu saja, ada beberapa item yang merupakan konsep kunci Relasional-atau-tidak, yang digabungkan, menyebabkan saya membuat kesimpulan yang begitu serius. Item lain tersebut berada di luar cakupan postingan ini.

Sepasang orang idiot saat ini sedang melakukan serangan terhadap Bentuk Normal Pertama. Mereka termasuk dalam rumah sakit jiwa.

Jawab

Sekarang untuk sisa pertanyaan Anda.

Apakah ada cara agar saya dapat membuat tabel relasional tanpa kehilangan fitur kenaikan otomatis?

Itu adalah kalimat yang bertentangan dengan diri sendiri. Saya percaya Anda akan mengerti dari penjelasan saya, tabel relasional tidak perlu untuk AUTOINCREMENT "fitur"; jika file memiliki AUTOINCREMENT , ini bukan tabel Relasional.

AUTOINCREMENT baik untuk satu hal saja:jika, dan hanya jika, Anda ingin membuat spreadsheet Excel dalam wadah database SQL, penuh dengan bidang bernama A, B, dan C, di bagian atas, dan mencatat nomor di sisi kiri. Dalam istilah database, itu adalah hasil dari SELECT, tampilan data yang rata, yaitu bukan sumber data, yang terorganisir (Normalized).

Solusi lain yang mungkin (tetapi tidak disukai) mungkin ada kunci utama lain di tabel pertama, yang merupakan nama pengguna pengguna, bukan dengan pernyataan kenaikan otomatis, tentu saja. Apakah itu tak terelakkan?

Dalam pekerjaan teknis, kami tidak peduli dengan preferensi, karena itu subjektif, dan itu berubah setiap saat. Kami peduli dengan kebenaran teknis, karena itu objektif, dan tidak berubah.

Ya, itu tidak bisa dihindari. Karena ini hanya masalah waktu; jumlah bug; jumlah "tidak bisa"; jumlah teriakan pengguna, sampai Anda menghadapi fakta, mengatasi pernyataan palsu Anda, dan menyadari bahwa:

  • satu-satunya cara untuk memastikan bahwa pengguna baris unik, nama_pengguna itu unik, adalah untuk mendeklarasikan UNIQUE kendala di atasnya

  • dan singkirkan user_id atau id di file pengguna

  • yang mempromosikan user_name ke PRIMARY KEY

Ya, karena seluruh masalah Anda dengan tabel ketiga, bukan kebetulan, kemudian dihilangkan.

Tabel ketiga itu adalah Tabel Asosiatif . Satu-satunya Kunci yang diperlukan (Kunci Utama) adalah gabungan dari dua Kunci Utama induk. Itu memastikan keunikan baris , yang diidentifikasi oleh Kunci mereka, bukan dengan IDs.

Saya memperingatkan Anda tentang itu karena "guru" yang sama yang mengajari Anda kesalahan dalam menerapkan ID bidang, ajarkan kesalahan penerapan ID bidang di Tabel Asosiatif, di mana, seperti halnya tabel biasa, itu berlebihan, tidak memiliki tujuan, memperkenalkan duplikat, dan menyebabkan kebingungan. Dan itu berlebihan karena dua kunci yang disediakan sudah ada di sana, menatap wajah kita.

Karena mereka tidak mengerti RM , atau istilah Relasional, mereka menyebut Tabel Asosiatif "tautan" atau "peta" tabel. Jika mereka memiliki ID lapangan, mereka sebenarnya adalah file.

Tabel Pencarian

ID bidang khususnya Hal Bodoh untuk Dilakukan untuk tabel Pencarian atau Referensi. Kebanyakan dari mereka memiliki kode yang dapat dikenali, tidak perlu menyebutkan daftar kode di dalamnya, karena kodenya (harus) unik.

Lebih lanjut, memiliki kode di tabel anak sebagai FK, adalah Hal yang Baik:kode jauh lebih bermakna, dan sering menyimpan gabungan yang tidak perlu:

    SELECT ...
        FROM child_table           -- not the lookup table
        WHERE gender_code = "M"    -- FK in the child, PK in the lookup

bukannya:

    SELECT ...
        FROM child_table
        WHERE gender_id = 6        -- meaningless to the maintainer

atau lebih buruk:

    SELECT ...
        FROM child_table C         -- that you are trying to determine
        JOIN lookup_table L
            ON C.gender_id = L.gender_id
        WHERE L.gender_code = "M"  -- meaningful, known

Perhatikan bahwa ini adalah sesuatu yang tidak dapat dihindari:Anda memerlukan keunikan pada kode pencarian dan keunikan pada deskripsi. Itulah satu-satunya metode untuk mencegah duplikat di setiap dari dua kolom:

    CREATE TABLE gender (
        gender_code  CHAR(2)  NOT NULL,
        name         CHAR(30) NOT NULL

        CONSTRAINT PK 
            PRIMARY KEY ( gender_code )

        CONSTRAINT AK 
            UNIQUE ( name )
        )

Contoh Lengkap

Dari detail dalam pertanyaan Anda, saya menduga Anda memiliki sintaks SQL dan masalah definisi FK, jadi saya akan memberikan seluruh solusi yang Anda butuhkan sebagai contoh (karena Anda belum memberikan definisi file):

    CREATE TABLE user (                 -- Typical Identifying Table
        user_name  CHAR(16) NOT NULL,   -- Short PK
        name_first CHAR(30) NOT NULL,   -- Alt Key.1
        name_last  CHAR(30) NOT NULL,   -- Alt Key.2
        birth_date DATE     NOT NULL    -- Alt Key.3

        CONSTRAINT PK                   -- unique user_name
            PRIMARY KEY ( user_name )

        CONSTRAINT AK                   -- unique person identification
            PRIMARY KEY ( name_last, name_first, birth_date )
        )

    CREATE TABLE sport (                  -- Typical Lookup Table
        sport_code  CHAR(4)  NOT NULL,    -- PK Short code
        name        CHAR(30) NOT NULL     -- AK

        CONSTRAINT PK 
            PRIMARY KEY ( sport_code )

        CONSTRAINT AK 
            PRIMARY KEY ( name )
        )

    CREATE TABLE user_sport (           -- Typical Associative Table
        user_name  CHAR(16) NOT NULL,   -- PK.1, FK
        sport_code CHAR(4)  NOT NULL,   -- PK.2, FK
        start_date DATE     NOT NULL

        CONSTRAINT PK 
            PRIMARY KEY ( user_name, sport_code )

        CONSTRAINT user_plays_sport_fk
            FOREIGN KEY     ( user_name )
            REFERENCES user ( user_name )

        CONSTRAINT sport_occupies_user_fk
            FOREIGN KEY      ( sport_code )
            REFERENCES sport ( sport_code )
        )

Di sana, PRIMARY KEY deklarasi jujur, itu adalah Kunci Utama; tidak ada ID; tidak ada AUTOINCREMENT; tidak ada indeks tambahan; tidak ada baris duplikat; tidak ada harapan yang salah; tidak ada masalah konsekuensial.

Model Data

Berikut adalah Model Data yang sesuai dengan definisinya.

  • Contoh Model Data Olahraga Pengguna

  • Jika Anda tidak terbiasa dengan Notasi, harap diperhatikan bahwa setiap centang, takik, dan tanda kecil, garis padat vs putus-putus, sudut persegi vs sudut bulat, berarti sesuatu yang sangat spesifik. Lihat Notasi IDEF1X .

  • Sebuah gambar bernilai seribu kata; dalam hal ini gambar keluhan standar bernilai lebih dari itu; yang buruk tidak sebanding dengan kertas yang digambarnya.

  • Silakan periksa Frasa Verb dengan hati-hati, mereka terdiri dari satu set Predikat. Sisa dari Predikat dapat ditentukan langsung dari model. Jika ini tidak jelas, silakan bertanya.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL DELETE FROM dengan subquery sebagai syarat

  2. MySQL :tidak ada di GROUP BY

  3. TO_SECONDS() Contoh – MySQL

  4. MySQL Query Untuk Mendapatkan Produk Terlaris

  5. Kelambatan ditemukan ketika gambar dasar 64 memilih dan mengkodekan dari database