PostgreSQL - masukkan / perbarui melanggar batasan kunci asing

12

Saya yang baru di postgreSQL. Saya punya 3 tabel, satu tabel referensi kunci utama 2 tabel lainnya. Tapi saya tidak bisa memasukkan data ke dalam Table3. Lihat kode di bawah ini:

DROP TABLE Table1 CASCADE;
CREATE TABLE Table1(
  "DataID" bigint NOT NULL DEFAULT '0',
  "AdData" integer DEFAULT NULL,
  PRIMARY KEY ("DataID")
);

DROP TABLE IF EXISTS Table2 CASCADE;
CREATE TABLE Table2 (
  "Address" numeric(20) NOT NULL DEFAULT '0',
  "Value" numeric(20) DEFAULT NULL,
  PRIMARY KEY ("Address")
);

DROP TABLE IF EXISTS Table3 CASCADE; 
CREATE TABLE table3 (   
  "ID" bigint NOT NULL DEFAULT '0',   
  "DataID" bigint DEFAULT NULL,   
  "Address" numeric(20) DEFAULT NULL,   
  "Data" bigint DEFAULT NULL,
   PRIMARY KEY ("ID"),   
   FOREIGN KEY ("DataID") REFERENCES Table1("DataID") on delete cascade on update cascade,   
   FOREIGN KEY ("Address") REFERENCES Table2("Address") on delete cascade on update cascade
);

GALAT: menyisipkan atau memperbarui pada tabel "Table3" melanggar batasan kunci asing "Table3_DataID_fkey" DETAIL: Key (DataID) = (27856) tidak ada dalam tabel "Table1".

Ketika saya mencoba memasukkan data ke dalam 3 tabel, terjadi kesalahan. Saya merujuk dokumentasi postgreSQL dan mengubah kode saya sebagai berikut: (Sayangnya itu menunjukkan kesalahan lain)

DROP TABLE Table1 CASCADE;
CREATE TABLE Table1(
  "DataID" bigint NOT NULL DEFAULT '0',
  "AdData" integer DEFAULT NULL,
  PRIMARY KEY ("DataID")
);

DROP TABLE IF EXISTS Table2 CASCADE;
CREATE TABLE Table2 (
  "Address" numeric(20) NOT NULL DEFAULT '0',
  "Value" numeric(20) DEFAULT NULL,
  PRIMARY KEY ("Address")
);

DROP TABLE IF EXISTS Table3 CASCADE; 
CREATE TABLE table3 (   
  "ID" bigint NOT NULL DEFAULT '0',   
  "DataID" bigint DEFAULT NULL REFERENCES Table1 ON DELETE RESTRICT,
  "Address" numeric(20) DEFAULT NULL REFERENCES Table2 ON DELETE CASCADE, 
  "Data" bigint DEFAULT NULL,
   PRIMARY KEY ("ID"),   
   PRIMARY KEY("DataID", "Address")
);

GALAT: beberapa kunci utama untuk tabel "Table3" tidak diperbolehkan LINE 65: KUNCI UTAMA ("DataID", "Address")

Tolong bantu saya ... Bagaimana saya bisa membuat referensi?

Saya mengubah IDas UNIQUEdan menghapus garis PRIMARY KEY ("ID"). Pada saat itu ia menunjukkan kesalahan lain seperti:

GALAT: nilai kunci duplikat melanggar batasan unik "Table3_pkey"

Haseena
sumber

Jawaban:

17

Ada beberapa masalah dengan tabel Anda. Saya akan mencoba untuk mengatasi kunci asing terlebih dahulu, karena Anda bertanya tentang hal itu :)

Tetapi sebelum itu, kita harus menyadari bahwa dua set tabel (tiga set pertama yang Anda buat dan set kedua, yang Anda buat setelah menjatuhkan set pertama) adalah sama. Tentu saja, definisi Table3dalam upaya kedua Anda memiliki kesalahan sintaks dan logis, tetapi ide dasarnya adalah:

CREATE TABLE table3 (   
  "ID" bigint NOT NULL DEFAULT '0',   
  "DataID" bigint DEFAULT NULL,   
  "Address" numeric(20) DEFAULT NULL,   
  "Data" bigint DEFAULT NULL,
   PRIMARY KEY ("ID"),   
   FOREIGN KEY ("DataID") REFERENCES Table1("DataID") on delete cascade on update cascade,   
   FOREIGN KEY ("Address") REFERENCES Table2("Address") on delete cascade on update cascade
);

Definisi ini memberi tahu PostgreSQL kira-kira sebagai berikut: "Buat tabel dengan empat kolom, satu akan menjadi kunci utama (PK), yang lain bisa NULL. Jika baris baru dimasukkan, periksa DataIDdan Address: jika mengandung nilai bukan-NULL ( mengatakan 27.856), kemudian memeriksa Table1untuk DataIDdan Table2untuk Address. Jika tidak ada nilai seperti di tabel tersebut, kemudian kembali kesalahan." Poin terakhir yang Anda lihat pertama kali:

ERROR: insert or update on table "Table3" violates foreign key constraint 
    "Table3_DataID_fkey" DETAIL: Key (DataID)=(27856) is not present in table "Table1".

Sangat sederhana: jika tidak ada baris di Table1mana DataID = 27856, maka Anda tidak dapat memasukkan baris itu ke dalam Table3.

Jika Anda membutuhkan baris itu, Anda harus terlebih dahulu menyisipkan baris ke Table1dengan DataID = 27856, dan hanya kemudian mencoba untuk memasukkan ke dalam Table3. Jika menurut Anda ini bukan yang Anda inginkan, jelaskan dalam beberapa kalimat apa yang ingin Anda capai, dan kami dapat membantu dengan desain yang baik.


Dan sekarang tentang masalah lainnya.

Anda mendefinisikan PK Anda sebagai

CREATE all_your_tables (
    first_column NOT NULL DEFAULT '0',   
    [...]
    PRIMARY KEY ("ID"),  

Kunci utama berarti bahwa semua item di dalamnya berbeda satu sama lain, yaitu nilainya UNIQUE. Jika Anda memberikan kolom statis DEFAULT(seperti '0') UNIQUE, Anda akan mengalami kejutan buruk sepanjang waktu. Ini adalah apa yang Anda dapatkan di pesan kesalahan ketiga Anda.

Lebih jauh lagi, '0'berarti string teks, tetapi bukan angka ( bigintatau numericdalam kasus Anda). Gunakan hanya 0sebagai gantinya (atau jangan gunakan sama sekali, seperti yang saya tulis di atas).

Dan poin terakhir (saya mungkin salah di sini): di Table2, Addressbidang Anda diatur ke numeric(20). Pada saat yang sama, itu adalah PK tabel. Nama kolom dan tipe data menunjukkan bahwa alamat ini dapat berubah di masa mendatang. Jika ini benar, maka itu adalah pilihan yang sangat buruk untuk PK. Pikirkan skenario berikut ini: Anda memiliki alamat '1234567890454', yang memiliki anak Table3seperti

ID        DataID           Address             Data
123       3216547          1234567890454       654897564134569

Sekarang alamat itu berubah menjadi sesuatu yang lain. Bagaimana Anda membuat baris anak Anda Table3mengikuti orang tuanya ke alamat baru? (Ada solusi untuk ini, tetapi dapat menyebabkan banyak kebingungan.) Jika ini adalah kasus Anda, tambahkan kolom ID ke tabel Anda, yang tidak akan berisi informasi apa pun dari dunia nyata, itu hanya akan berfungsi sebagai nilai identifikasi (yaitu , ID) untuk suatu alamat.

dezso
sumber
Terima kasih atas saran Anda yang berharga. Saya akan mencoba desain yang lebih baik berdasarkan saran Anda. Sekarang kesalahan pertama teratasi.
Haseena
0

Itu semua tergantung pada apa yang ingin Anda lakukan dengan data.

Contoh pertama - Anda ingin memiliki data yang konsisten di semua tabel, tetapi Anda mencoba memasukkan nilai yang tidak cocok dengan Table1.

Contoh kedua - Anda tidak ingin memiliki data yang konsisten, tetapi coba lakukan sesuatu yang lain, tidak tahu persis apa. Tabel tidak boleh memiliki lebih dari satu kunci utama.

Contoh ketiga - Anda masih tidak tahu apa yang ingin Anda capai dan menempatkan batasan UNIK pada kolom yang mungkin memiliki nilai yang sama beberapa kali.

Jika Anda hanya ingin memasukkan data Anda - singkirkan referensi kunci asing pada contoh pertama. Jika Anda ingin memiliki data yang konsisten di semua tabel - lakukan pembersihan data lalu masukkan dalam tabel DENGAN batasan kunci asing.

tl; dr: untuk menyisipkan data Anda ke dalam Table3 dengan kode dari contoh pertama - masukkan nilai yang hilang ke dalam kolom Table1.DataID yang ada di Table3.DataId.

BartekR
sumber