Trong một ứng dụng Web tôi đang làm việc, tất cả các hoạt động cơ sở dữ liệu được trừu tượng hóa bằng cách sử dụng một số kho lưu trữ chung được xác định trên Entity Framework ORM.
Tuy nhiên, để có một thiết kế đơn giản cho các kho lưu trữ chung, tất cả các bảng liên quan phải xác định một số nguyên duy nhất ( Int32
trong C #, int
trong SQL). Cho đến bây giờ, điều này luôn luôn là PK của bảng và cũng là IDENTITY
.
Khóa ngoại được sử dụng nhiều và chúng tham chiếu các cột số nguyên này. Chúng được yêu cầu cho cả tính nhất quán và để tạo các thuộc tính điều hướng bởi ORM.
Lớp ứng dụng thường thực hiện các thao tác sau:
- tải dữ liệu ban đầu từ bảng (*) -
SELECT * FROM table
- Cập nhật -
UPDATE table SET Col1 = Val1 WHERE Id = IdVal
- Xóa -
DELETE FROM table WHERE Id = IdVal
- Chèn -
INSERT INTO table (cols) VALUES (...)
Hoạt động ít thường xuyên hơn:
- Chèn hàng loạt -
BULK INSERT ... into table
theo sau (*) bởi tất cả tải dữ liệu (để truy xuất số nhận dạng được tạo) - Xóa hàng loạt - đây là thao tác xóa bình thường, nhưng "cồng kềnh" theo quan điểm của ORM:
DELETE FROM table where OtherThanIdCol = SomeValue
- Cập nhật hàng loạt - đây là hoạt động cập nhật bình thường, nhưng "cồng kềnh" theo quan điểm của ORM:
UPDATE table SET SomeCol = SomeVal WHERE OtherThanIdCol = OtherValue
* tất cả các bảng nhỏ được lưu trữ ở cấp ứng dụng và hầu như tất cả SELECTs
sẽ không đến được cơ sở dữ liệu. Một mô hình điển hình là tải ban đầu và rất nhiều INSERT
s, UPDATE
s và DELETE
s.
Dựa trên việc sử dụng ứng dụng hiện tại, có rất ít khả năng đạt được 100 triệu bản ghi trong bất kỳ bảng nào.
Câu hỏi: Từ quan điểm của một DBA, có vấn đề đáng kể nào tôi có thể gặp phải khi giới hạn thiết kế bảng này không?
[CHỈNH SỬA]
Sau khi đọc câu trả lời (cảm ơn về phản hồi tuyệt vời) và các bài viết được tham khảo, tôi cảm thấy mình phải thêm chi tiết:
Thông tin cụ thể về ứng dụng hiện tại - Tôi không đề cập đến ứng dụng web hiện tại, vì tôi muốn hiểu liệu mô hình có thể được sử dụng lại cho các ứng dụng khác không. Tuy nhiên, trường hợp cụ thể của tôi là một ứng dụng trích xuất rất nhiều siêu dữ liệu từ DWH. Dữ liệu nguồn khá lộn xộn (không chuẩn hóa theo cách kỳ lạ, có một số điểm không nhất quán, không có định danh tự nhiên trong nhiều trường hợp, v.v.) và ứng dụng của tôi đang tạo ra các thực thể tách biệt rõ ràng. Ngoài ra, nhiều số nhận dạng được tạo (
IDENTITY
) được hiển thị để người dùng có thể sử dụng chúng làm khóa doanh nghiệp. Điều này, bên cạnh việc tái cấu trúc mã lớn, không bao gồm việc sử dụng GUID ."Họ không nên là cách duy nhất để xác định một hàng duy nhất" (Aaron Bertrand ♦) - đó là một lời khuyên rất tốt. Tất cả các bảng của tôi cũng xác định một CONSTRAINT ĐỘC ĐÁO để đảm bảo rằng các bản sao kinh doanh không được phép.
Thiết kế hướng ứng dụng phía trước so với thiết kế hướng cơ sở dữ liệu - lựa chọn thiết kế là do các yếu tố này gây ra
Giới hạn khung thực thể - cho phép nhiều cột PK, nhưng giá trị của chúng không thể được cập nhật
Giới hạn tùy chỉnh - có một khóa số nguyên đơn giản hóa rất nhiều cấu trúc dữ liệu và mã không phải SQL. Ví dụ: tất cả danh sách các giá trị đều có khóa nguyên và giá trị được hiển thị. Quan trọng hơn, nó đảm bảo rằng bất kỳ bảng nào được đánh dấu cho bộ đệm sẽ có thể được đưa vào
Unique int key -> value
bản đồ.
Các truy vấn chọn phức tạp - điều này hầu như sẽ không bao giờ xảy ra vì tất cả dữ liệu bảng nhỏ (<20-30K) được lưu trong bộ nhớ ứng dụng ở cấp ứng dụng. Điều này làm cho cuộc sống khó khăn hơn một chút khi viết mã ứng dụng (viết LINQ khó hơn), nhưng cơ sở dữ liệu được đánh đẹp hơn nhiều:
Danh sách lượt xem - sẽ không tạo ra
SELECT
các truy vấn khi tải (mọi thứ được lưu trong bộ nhớ cache) hoặc các truy vấn trông như thế này:SELECT allcolumns FROM BigTable WHERE filter1 IN (val1, val2) AND filter2 IN (val11, val12)
Tất cả các giá trị bắt buộc khác được tìm nạp thông qua tra cứu bộ đệm (O (1)), do đó sẽ không có truy vấn phức tạp nào được tạo.
Chỉnh sửa chế độ xem - sẽ tạo ra các
SELECT
câu lệnh như thế này:SELECT allcolumns FROM BigTable WHERE PKId = value1
(tất cả các bộ lọc và giá trị là int
s)