Mọi câu chuyện tuyệt vời đều bắt đầu với một cuộc khủng hoảng danh tính. Luke, Jedi Master vĩ đại, bắt đầu không chắc chắn - "Tôi là ai?" - và làm thế nào tôi có thể là bất cứ ai quan trọng? Phải cần đến Yoda, người có Thần lực, dạy anh ta cách khai thác sức mạnh của mình.
Hôm nay, hãy để tôi là Yoda của bạn.
Chúng tôi sẽ bắt đầu với cách chọn Khóa chính, chống khủng hoảng danh tính và sau đó kết thúc với các mẫu mã để tạo Khóa chính trong cơ sở dữ liệu.
Cách Chọn Khóa Chính
Bạn có thể nghĩ Luke là người duy nhất bị khủng hoảng danh tính, nhưng điều đó không đúng. Khi tạo cơ sở dữ liệu, mọi thứ đều rơi vào tình trạng khủng hoảng danh tính. Và đó chính xác là lý do tại sao chúng ta cần khóa chính:chúng giải quyết khủng hoảng. Họ cho chúng tôi biết cách tìm kiếm tất cả mọi người.
Hãy tưởng tượng bạn là chính phủ và bạn muốn xác định từng công dân của mình bằng kỹ thuật số. Vì vậy, bạn tạo cơ sở dữ liệu này với mọi thứ về chúng:
First Name
Last Name
Passport Number
Bạn chọn Số hộ chiếu làm Khóa chính - danh tính cho tất cả mọi người. Bạn nghĩ đó là tất cả những gì bạn cần vì hộ chiếu có địa chỉ và mọi thứ khác. Bạn biết rằng số hộ chiếu là duy nhất, vì vậy bạn cảm thấy hài lòng và triển khai hệ thống này.
Sau đó, vài năm sau, bạn phát hiện ra một sự thật tồi tệ:cả đất nước đang phải đối mặt với cuộc khủng hoảng danh tính.
Bất cứ khi nào hộ chiếu của ai đó hết hạn, họ sẽ nhận được một cái mới. Danh tính của họ thay đổi. Các hệ thống khác tiếp tục sử dụng số hộ chiếu cũ, vì vậy chúng hiện chỉ ra người ma.
Duy nhất là không đủ. Giá trị không được thay đổi trong suốt thời gian tồn tại của hàng.
Và sau đó, bạn thấy có một số người thậm chí không có hộ chiếu. Bạn không thể nhập chúng vào hệ thống của mình, vì các Khóa chính không thể là NULL
. Làm cách nào bạn có thể xác định ai đó bằng NULL
phím?
Mỗi hàng phải có một mã định danh. Không cho phép NULL.
Lần lặp tiếp theo có nghĩa là tìm một số nhận dạng không thay đổi theo thời gian và một số mà mọi người đều có. Ở Ấn Độ, đây hóa ra là Thẻ Adhaar. Ở Hoa Kỳ, Số An sinh Xã hội.
Nếu bạn đang tạo cơ sở dữ liệu, hãy đặt những khóa đó làm khóa chính của bạn.
Đôi khi, bạn không có bất kỳ chìa khóa nào như vậy. Hãy xem xét một quốc gia chưa có Số an sinh xã hội và họ muốn tạo hồ sơ kỹ thuật số về mọi công dân. Họ có thể tạo một SSN mới hoặc họ chỉ có thể tận dụng sức mạnh của cơ sở dữ liệu và sử dụng khóa thay thế.
Một khóa thay thế không có tương đương trong thế giới thực. Nó chỉ là một số bên trong cơ sở dữ liệu. Vì vậy, bạn có bảng này ở quốc gia mới:
userID
First Name
Last Name
Passport Number
Số hộ chiếu là duy nhất. Bất cứ khi nào bạn muốn lấy số nhận dạng cho người dùng, bạn có thể lấy nó qua Số hộ chiếu.
UserID không bao giờ thay đổi. Số Hộ chiếu có thể thay đổi - nhưng nó luôn là duy nhất, vì vậy bạn luôn có được người dùng phù hợp. UserID là một người đại diện cho một Số An sinh Xã hội không tồn tại ở quốc gia này.
Sự thật thú vị:Số Hộ chiếu ở đây cũng là một Chìa khóa Ứng viên. Nó có thể là Khóa chính, nếu nó không bao giờ thay đổi. Đây là sự khác biệt về logic kinh doanh.
Bài học rút ra chính là: Bất cứ khi nào bạn chọn Khóa chính, hãy nghĩ đến cuộc khủng hoảng danh tính . Có khả năng ai đó có thể thay đổi số nhận dạng của họ trong tương lai không? Chúng ta có thể vào trạng thái có nhiều người có cùng số nhận dạng không?
Tôi lấy mọi người làm ví dụ, bởi vì nó làm cho danh tính rõ ràng hơn - chúng tôi biết mỗi người phải có một danh tính. Chuyển suy nghĩ này vào cơ sở dữ liệu của bạn. Mọi thứ đều có danh tính, đó chính là lý do tại sao bạn cần Khóa chính.
Lưu ý:Đôi khi, có thể và mong muốn sử dụng nhiều cột cùng nhau làm Khóa chính. Đây là một khóa tổng hợp.
Bây giờ chúng ta hãy thử xác định Khóa chính bằng các ví dụ mã thực. Có hai việc cần làm ở đây:trước tiên, bạn sẽ xác định được Khóa chính. Sau đó, bạn sẽ học cú pháp để xác định nó trong cơ sở dữ liệu.
Một ví dụ trong thế giới thực
Giả sử bạn điều hành một công ty khởi nghiệp vận chuyển, giống như Flexport. Bạn có các gói hàng cần vận chuyển từ nơi này đến nơi khác và tàu vận chuyển chúng. Hơn nữa, bạn có những khách hàng đang đặt hàng các gói này.
Bạn nghĩ rằng bạn sẽ cần một bảng cho khách hàng, một bảng cho các gói hàng và một bảng để vận chuyển, cho biết gói hàng nào hiện đang ở đâu.
Hãy suy nghĩ về những cột nào bạn sẽ cần và những gì nên là Khóa chính. Nếu bạn là một kỹ sư tại Flexport, đây là một câu hỏi thực tế mà bạn sẽ phải tìm ra. Không có gì được cho, mọi thứ đều được khám phá trong thế giới thực.
Với thông tin này, tôi thiết kế các bảng này như vậy:
Customers: first_name, last_name, email, address (for deliveries to their location)
Packages: weight, content
Transportation: <package_primary_key>, Port, time
Chúng tôi đang thiếu các khóa chính. Hãy nghĩ về chúng trước khi đọc thêm.
Đối với gói hàng, tôi sẽ chọn một người thay thế PackageID. Tôi có thể đã cố gắng liệt kê tất cả các thuộc tính của gói:trọng lượng, thể tích, mật độ, tuổi. Họ sẽ xác định duy nhất gói, nhưng điều này rất khó thực hiện trong thực tế. Mọi người không quan tâm đến điều này, họ chỉ quan tâm đến việc gói hàng đi từ nơi này đến nơi khác.
Vì vậy, rất hợp lý khi tạo một số ngẫu nhiên và sử dụng số đó làm ID. Đây chính là lý do tại sao bạn thấy FedEx, UPS và mọi dịch vụ chuyển phát đều sử dụng mã vạch và ID. Đây là các khóa thay thế được tạo để theo dõi các gói.
Đối với khách hàng, tôi sẽ chọn một người thay thế ID khách hàng. Ở đây, một lần nữa, tôi có một tùy chọn để chọn, chẳng hạn như Số an sinh xã hội của khách hàng của tôi. Tuy nhiên, khách hàng không muốn chia sẻ điều này với tôi chỉ để tôi có thể giao hàng cho họ. Do đó, chúng tôi tạo một khóa nội bộ, không cho khách hàng biết về khóa này và tiếp tục gọi họ là CustomerNo. 345681.
Câu chuyện thú vị:Tôi biết một vài công ty nơi họ tiếp xúc với CustomerNo này, và khách hàng khẳng định rằng họ nhận được vị trí số 1. Điều đó khá vui nhộn - các kỹ sư thực sự đã phải thay đổi mã giao diện người dùng của họ thành:if (cust == 345681) print(1);
Đối với Giao thông vận tải, tôi sẽ chọn hỗn hợp PackageID + Cổng + thời gian. Điều này thú vị hơn một chút. Tôi có thể đã tạo một người đại diện ở đây, và nó sẽ hoạt động tốt.
Nhưng, điều kỳ diệu của việc lập chỉ mục nằm ở đây. Các Khóa chính nhận chỉ mục tự động, có nghĩa là tìm kiếm hiệu quả hơn nhiều so với các Khóa chính.
Khi bạn đang tìm kiếm thông qua cơ sở dữ liệu này, hầu hết các truy vấn sẽ có dạng "gói này ở đâu?". Nói cách khác, với PackageID này, hãy cho tôi biết Cổng và Thời gian hiện tại. Tôi sẽ cần một chỉ mục bổ sung trên PackageID nếu tôi không có nó như một phần của Khóa chính của mình.
Điều này có âm thanh tốt? Bước cuối cùng, hãy xác định 3 bảng này trong SQL. Cú pháp thay đổi một chút với cơ sở dữ liệu bạn đang sử dụng.
Xác định Khóa chính trong MySQL
CREATE TABLE customers
( customerID INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
email VARCHAR(50) NOT NULL,
address VARCHAR(300)
);
CREATE TABLE packages
( packageID INT(15) NOT NULL AUTO_INCREMENT,
weight DECIMAL (10, 2) NOT NULL,
content VARCHAR(50),
CONSTRAINT packages_pk PRIMARY KEY (packageID) # An alternative way to above,
# when you want to name the constraint as well.
);
CREATE TABLE transportation
( package INT(15) NOT NULL,
port INT(15) NOT NULL,
time DATE NOT NULL,
PRIMARY KEY (package, port, time),
FOREIGN KEY package
REFERENCES packages(packageID)
ON DELETE RESTRICT # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
);
Xác định Khóa chính trong PostgreSQL
CREATE TABLE customers
( customerID SERIAL NOT NULL PRIMARY KEY, # In PostgreSQL SERIAL is same as AUTO_INCREMENT - it adds 1 to every new row.
last_name VARCHAR(30) NOT NULL,
first_name VARCHAR(25) NOT NULL,
address TEXT,
email VARCHAR(50) NOT NULL
);
CREATE TABLE packages
( packageID SERIAL NOT NULL,
weight NUMERIC NOT NULL,
content TEXT,
CONSTRAINT packages_pk PRIMARY KEY (packageID) # In PostgreSQL, this alternative way works too.
);
CREATE TABLE transportation
( package INTEGER NOT NULL,
port INT(15) NOT NULL,
time DATE NOT NULL,
PRIMARY KEY (package, port, time),
FOREIGN KEY package
REFERENCES packages(packageID)
ON DELETE RESTRICT # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
);
Nó không khác lắm, phải không? Khi bạn đã nắm được những kiến thức cơ bản, bạn có thể áp dụng nó cho hầu hết mọi cơ sở dữ liệu chỉ bằng cách xem nhanh tài liệu. Điều quan trọng là biết những gì cần tìm!
Chúc may mắn, padawan trẻ.
Rất thích điều này? Bạn cũng có thể thích Những điều tôi học được từ một kỹ sư phần mềm cao cấp