Kesalahan Anda disebabkan karena sintaks kunci asing yang salah.
Namun, Saya pikir Anda harus menggunakan bidang ID daripada melakukan kunci utama komposit string . Ada beberapa masalah dengan metode Anda...
-
Ini akan mempersulit DB untuk menggabungkan tabel bersama dibandingkan dengan menggunakan bidang integer (ID) untuk bergabung (lebih sulit ==lebih banyak waktu pemrosesan).
-
Adalah sah untuk memiliki beberapa orang dengan nama yang sama, bahkan menggunakan inisial tengah.
-
Apa yang terjadi jika Anda harus mengubah nama seseorang? Entah karena salah simpan atau mereka menikah atau apa... Itu berarti Anda tidak hanya harus memperbarui
employee
Anda tabel, tetapiworks
tabel dan tabel lain yang Anda gunakan namanya sebagai kunci asing.
Lihat ini:http://sqlfiddle.com/#! 2/2dc8c/3/0
Saya telah menambahkan ID tabel ke setiap tabel . Ini adalah unsigned int
, yang berarti tidak boleh negatif (karena itu tidak masuk akal). Itu juga auto_increment
, yang berarti bahwa setiap kali Anda menambahkan baris ke tabel, ID ini akan dibuat secara otomatis dan naik 1.
create table Employee (
Employee_ID int unsigned auto_increment primary key,
Lastname varchar(10),
FirstName varchar(10),
MidInitial char(1),
gender char(1),
street varchar(10),
city varchar(10),
unique (Lastname, FirstName, MidInitial)
);
Anda akan menambahkan sesuatu ke tabel ini seperti ini:
insert into Employee (Employee_ID, LastName, FirstName, MidInitial)
values (null, 'Smith', 'John', 'K');
null
akan menjadi ID yang dibuat secara otomatis. Ini akan menjadi unik untuk setiap baris.
Juga, batasan unik berarti kombinasi bidang ini harus unik dalam tabel. Namun, dengan perusahaan yang cukup besar, saya yakin dua orang akan memiliki nama yang sama. Dalam kehidupan nyata, saya akan menyarankan untuk menghapus batasan unik ini.
Saya membuat perubahan serupa pada tabel perusahaan...
create table company(
company_ID int unsigned auto_increment primary key,
company_name varchar(20),
city varchar(10),
unique (company_name)
);
Hal-hal yang dapat ditambahkan seperti:
insert into company values (null, 'Taco Bell', 'Paris');
Jadi... untuk works
.... daripada menyimpan nama lengkap setiap orang dan nama lengkap perusahaan berulang-ulang di tabel ini, sekarang kita hanya perlu menyimpan ID-nya.
create table Works (
works_id int unsigned auto_increment primary key,
employee_id int unsigned,
compay_id int unsigned,
salary numeric(8,2),
foreign key (employee_id) references Employee (employee_id),
foreign key (compay_id) references company (company_id)
);
Anda dapat menambahkan sesuatu ke works
seperti ini:
insert into Works values (null, 1, 1, '10.00');
Karena John Smith adalah karyawan pertama kami, Employee_ID-nya akan menjadi 1. Untuk memverifikasi itu, coba saja select * from Employee where FirstName='John' and LastName='Smith'
. Taco Bell juga akan mendapatkan company_id =1. Dengan memasukkan nilai-nilai tersebut ke dalam works
, itu berarti John sekarang bekerja di Taco Bell.
Saya juga menyarankan Anda menambahkan bidang seperti start_date
dan end_date
dan job_title
ke meja kerja Anda. Dan Anda juga ingin memberikan pertimbangan khusus pada batasan unik apa pun untuk tabel ini. Orang dapat bekerja untuk perusahaan yang sama lebih dari sekali. Mereka juga dapat memiliki pekerjaan yang berbeda.
Saat Anda ingin mendapatkan kembali data Anda, Anda akan menggunakan kueri seperti ini:
select FirstName, MidInitial, LastName,
Company_Name,
Salary
from employee
join works
on works.employee_id = employee.employee_id
join company
on works.company_id = company.company_id
yang merupakan cara yang bagus untuk mengatakan ini:
select FirstName, MidInitial, LastName,
Company_Name,
Salary
from employee, works, company
where employee.employee_id = works.employee_id and
company.company_id = works.company_id
Beberapa catatan tentang database...
-
Pilih konvensi penamaan dan patuhi itu! Jika Anda ingin menggunakan
CamelCase
, gunakan di mana-mana. Jikayou_want_to_use
menggarisbawahi nama Anda, gunakan di mana-mana. Ada banyak konvensi penamaan untuk dipilih:atribut awalan (kolom/bidang) dengan nama tabel, menggunakan singkatan umum (atau tidak), di mana penggunaan huruf besar (atau tidak) ... ini sebagian besar tergantung pada preferensi pribadi tetapi ada adalah artikel di luar sana tentang pro dan kontra tentang penggunaan yang tertentu. Catatan terakhir, _hanya karena Anda dapat menggunakan spasi dalam sebuah nama,__ tidak berarti Anda harus melakukannya.`Almost all`
database membiarkan[you use spaces]
dalam nama jika Anda mau tetapi itu dapat menyebabkan banyak masalah nanti. -
Nama tabel tidak boleh jamak. Ini adalah kekesalan saya dan inilah alasannya:Kami tahu sebuah tabel akan menyimpan banyak catatan... banyak orang/orang, banyak karyawan, banyak perusahaan, banyak entri dari jenis atau jenis apa pun. Setiap baris hanya menjelaskan satu dari hal-hal ini. Kadang-kadang bahkan tidak masuk akal untuk memiliki nama menjadi jamak. Di lain waktu, itu dipertanyakan - seperti
works
meja. Jika Anda terkadang membuatnya jamak, dan terkadang membuatnya tunggal, itu bisa membingungkan nanti. Dengan hanya menjadikannya tunggal, itu masih masuk akal, dan Anda tidak perlu bolak-balik atau harus mencari nama yang tepat saat menulis kueri. -
Tipe data itu penting dan coba konsisten di seluruh tabel untuk bidang serupa (seperti semua
id
s jenis yang sama; buat semua bidang boolean semua bit atau bilangan bulat atau apa pun, buat saja sama). Ada berbagai ukuran tipe integer yang dapat Anda pilih. Pikirkan tentang ukuran, kinerja, dan apa yang sesuai dengan kebutuhan Anda. Putuskan apakah Anda benar-benar membutuhkan nvarchar atau varchar tidak apa-apa.- Tanggal seharusnya tidak pernah disimpan sebagai string. Gunakan tipe data tanggal, tanggal, waktu, atau stempel waktu yang sesuai . Ini akan sangat membantu Anda nanti ketika Anda perlu mengambilnya, membandingkannya atau menggunakannya dalam perhitungan. Keputusan penting lainnya adalah bagaimana Anda memilih untuk menangani zona waktu . Saya suka menyimpan semuanya dalam UTC dan menangani hal-hal offset zona waktu apa pun di ujung depan, ketika info disajikan kepada pengguna. Ini menjaga semuanya tetap konsisten dan saya tidak perlu khawatir jika baris dimasukkan pada jam 6 sore berdasarkan waktu komputer pengguna saya, waktu browser pengguna, waktu database saya, atau waktu server.
- Tanggal seharusnya tidak pernah disimpan sebagai string. Gunakan tipe data tanggal, tanggal, waktu, atau stempel waktu yang sesuai . Ini akan sangat membantu Anda nanti ketika Anda perlu mengambilnya, membandingkannya atau menggunakannya dalam perhitungan. Keputusan penting lainnya adalah bagaimana Anda memilih untuk menangani zona waktu . Saya suka menyimpan semuanya dalam UTC dan menangani hal-hal offset zona waktu apa pun di ujung depan, ketika info disajikan kepada pengguna. Ini menjaga semuanya tetap konsisten dan saya tidak perlu khawatir jika baris dimasukkan pada jam 6 sore berdasarkan waktu komputer pengguna saya, waktu browser pengguna, waktu database saya, atau waktu server.
-
Sertakan
ID
bidang yang unik untuk baris di setiap tabel. Cara termudah untuk melakukannya adalah dengan menggunakanauto_increment
(mysql) atauidentity(1,1)
(sql server) sehingga database melacaknya untuk Anda. Nilai-nilai ini dapat direset atau di-reseed jika Anda membutuhkannya. -
Pelajari cara menggunakan normalisasi .
-
Pelajari apa transaksi lakukan dan mengapa itu penting... bahkan jika Anda tidak menggunakannya.
-
Pelajari tentang jenis gabungan yang berbeda . Ini adalah salah satu penjelasan terbaik pernah saya lihat. Hal utama yang harus diperhatikan adalah apakah joinnya harus outer atau inner join.
-
Pelajari tentang Injeksi SQL dan yang lebih penting, bagaimana untuk mencegahnya (tautan itu untuk PHP).
-
Jika Anda menggunakan PHP, jangan gunakan
mysql_
yang lama kelas. Sebagai gantinya, gunakanPDO
atauMySQLi_
. Info... -
Hal besar tentang database adalah integritas, validasi, dan sanitasi data . Pengguna akan ingin memasukkan semua jenis data yang ceroboh dan kotor ke dalam tabel Anda. Apakah itu MO atau Missouri? Perempuan, F, perempuan, perempuan, atau ya? Apakah gajinya 15,00 per jam, 50rb per tahun, atau 3.000 gaji? Apakah 31/12/2013, 31/12/2013, 31-12-13, 31 Desember 2013 atau tiga puluh lima desember dua ribu tiga belas?
-
Tentukan apakah Anda ingin mengizinkan
NULL
atau tidak. Itu membuat segalanya lebih rumit karena logika tiga keadaan dan Anda perlu memeriksanya nanti. Beberapa orang memutuskan untuk menggunakan string kosong saja. NULL lebih merupakan keadaan daripada nilai aktual dan itu berarti tidak terdefinisi atau tidak diketahui - nilainya bisa berupa apa saja. Saya menggunakan null karena string kosong terkadang merupakan nilai yang valid untuk suatu bidang. Misalnya, menyetelMiddle_Initial
untuk menyamakan string kosong bisa berarti orang tersebut tidak memiliki inisial tengah atau bisa berarti Anda tidak tahu apa itu. Bagi saya, hal-hal ini berbeda. Bagi orang lain, perbedaan itu tidak masalah. Pertimbangkan saja angka... apakah 0 sama dengan yang tidak diketahui? -
Jika tidak ada yang lain, tetaplah konsisten.