Thiết kế cơ sở dữ liệu: Bảng mới so với cột mới


38

(Điều này đã được đề xuất để được đăng lại ở đây từ StackOverflow)

Hiện tại có một bảng .. và cần bắt đầu thêm các cột dữ liệu mới vào đó. Không phải mọi bản ghi (thậm chí chuyển tiếp với dữ liệu mới sau khi thêm các cột dữ liệu mới) sẽ có dữ liệu. Vì vậy, tôi tự hỏi nếu điều này phù hợp hơn cho một bảng mới vì nó thực sự là một phần mở rộng của một số hàng dữ liệu và không áp dụng cho mỗi hàng.

Nói cách khác, vì sẽ có rất nhiều cột không được sử dụng cho các thành phần dữ liệu mới đó, có vẻ như điều này sẽ phù hợp hơn cho một bảng mới?

Bảng đầu tiên là bản ghi số lượt xem trang (hiện là 2 triệu bản ghi)

- ID
- Địa chỉ IP
- lần xem
- dấu thời gian created_at
- ngày

đối với mỗi địa chỉ IP, một bản ghi được tạo mỗi ngày - và số lần xem trang liên tiếp được thêm vào số lần xem mỗi ngày

(các) trường bổ sung sẽ dành cho điểm theo dõi xuất xứ (ví dụ: nguồn phân tích / phương tiện / chiến dịch của google)

Không phải mọi chuyến thăm sẽ có thông tin đó. Tôi sẽ cho rằng khoảng 10% các hàng sẽ có dữ liệu (vì nó thường chỉ được quy cho lần truy cập đầu tiên)

Việc sử dụng chính cho dữ liệu sẽ là thuộc tính nơi mọi người đến từ. Điều này có thể sẽ được sử dụng thường xuyên hơn (mà sau đó dường như cho vay vào bảng duy nhất)

Đánh giá cao thông tin phản hồi - có thể thêm nhiều hơn nếu cần

Câu trả lời:


29

Những gì bạn đang vật lộn với phân vùng dọc. Đây là một kỹ thuật thiết kế cơ sở dữ liệu vật lý để cải thiện hiệu suất. Như với bất kỳ kỹ thuật thiết kế cơ sở dữ liệu vật lý nào, khả năng ứng dụng của nó phụ thuộc vào các truy vấn cụ thể mà bạn đang cố gắng tối ưu hóa và liệu kỹ thuật này sẽ tối ưu hóa chúng. Từ quan điểm logic, nếu các trường mới này phụ thuộc vào khóa ứng cử viên cho thực thể của bạn thì chúng là sự thật về nó thuộc về nó. Trước tiên, bạn nên đảm bảo rằng bạn hiểu đầy đủ sự phụ thuộc chức năng của các trường mới này vào các khóa ứng viên của bạn để xác minh chúng thực sự là sự thật về lượt xem trang hàng ngày. Nếu có, quyết định phân vùng chúng vào một bảng khác là tối ưu hóa hiệu suất chỉ nên được thực hiện nếu nó đạt được mục tiêu hiệu suất của bạn.

Nói chung, phân vùng dọc rất hữu ích nếu bạn sẽ truy vấn các cột mới này không thường xuyên và khác biệt với các cột khác trong bảng gốc. Bằng cách đặt các cột đó vào một bảng khác có cùng PK với bảng hiện có của bạn, bạn có thể truy vấn trực tiếp khi bạn muốn các cột mới đó và nhận được nhiều hơn thông qua vì bạn sẽ có nhiều hàng hơn trên mỗi trang cho bảng mới này vì tất cả các cột trong bảng gốc sẽ không được ngồi trên các hàng đó. Tuy nhiên, nếu bạn sẽ luôn truy vấn các cột này cùng với các cột trong bảng gốc thì một phân vùng dọc sẽ không có ý nghĩa gì vì bạn sẽ luôn phải tham gia bên ngoài để có được chúng. Các trang từ các bảng trên đĩa đi vào vùng đệm của DBMS một cách độc lập, không bao giờ được nối trước, và do đó, việc nối sẽ phải xảy ra với mọi thực thi truy vấn ngay cả khi dữ liệu được ghim trong vùng đệm. Trong kịch bản này, việc tạo các cột NULLABLE trên bảng gốc sẽ cho phép công cụ lưu trữ DBMS lưu trữ chúng hiệu quả khi NULL và loại bỏ nhu cầu tham gia khi truy xuất.

Tôi nghe có vẻ như trường hợp sử dụng của bạn là trường hợp sau và thêm chúng dưới dạng NULLABLE vào bảng gốc của bạn là cách để đi. Nhưng như với mọi thứ khác trong thiết kế cơ sở dữ liệu, điều đó phụ thuộc và để đưa ra quyết định đúng đắn, bạn cần biết khối lượng công việc dự kiến ​​của mình và việc đưa ra lựa chọn tốt phụ thuộc vào điều gì. Một ví dụ điển hình về trường hợp sử dụng thích hợp cho phân vùng dọc sẽ là bảng tìm kiếm người, trong đó ứng dụng của bạn có một số thông tin rất hiếm khi được điền về một người mà ai đó có thể muốn tìm kiếm nhưng hiếm khi làm như vậy. Nếu bạn đặt thông tin đó vào một bảng khác, bạn có một số tùy chọn tốt cho hiệu suất. Bạn có thể viết tìm kiếm để bạn có 2 truy vấn - một truy vấn sử dụng thông tin chính, luôn được điền để tìm kiếm (như họ hoặc ssn), và một thông tin bên ngoài tham gia vào thông tin rất thường xuyên chỉ khi nó được yêu cầu tìm kiếm. Hoặc bạn có thể tận dụng trình tối ưu hóa DBMS nếu nó đủ thông minh để nhận ra một tập hợp các biến chủ đã cho mà không cần tham gia bên ngoài và sẽ không thực hiện nó, do đó bạn chỉ phải tạo 1 truy vấn.

Bạn đang sử dụng nền tảng DBMS nào? Cách thức nền tảng xử lý lưu trữ cột NULL, tối ưu hóa truy vấn của bạn, cũng như sự sẵn có của hỗ trợ cột thưa thớt (SQL Server có điều này) sẽ ảnh hưởng đến quyết định. Cuối cùng, tôi khuyên bạn nên thử cả hai thiết kế trong môi trường thử nghiệm với dữ liệu và khối lượng công việc có kích thước sản xuất và xem cái nào đạt được mục tiêu hiệu suất của bạn tốt hơn.


Tôi không rõ ý của bạn là gì bởi "Tuy nhiên, nếu bạn sẽ luôn truy vấn các cột này cùng với các cột trong bảng gốc thì một phân vùng dọc sẽ không có ý nghĩa gì vì bạn sẽ luôn phải tham gia bên ngoài để có được chúng." , bạn sẽ chỉ cần thực hiện một phép nối ngoài khi bạn muốn các cột chính cho dù các cột phụ có sẵn hay không, nếu không, bạn sử dụng INNER THAM GIA và làm như vậy có lợi trong hầu hết các trường hợp (giảm số lượng hàng nhìn vào ).
jmoreno

Cảm ơn tất cả sự giúp đỡ ở đây .. Tôi đã thực sự đi cùng với việc thêm các trường, nhưng sau khi suy nghĩ kỹ, tôi thấy rằng tôi nên có một vài bảng khác để xác định rõ hơn mọi thứ. Cuối cùng nó đã đến là visitor visitor_visits (trong đó có visitor_id và chứa nguồn) page_view (có vistor_id và visitor_visit_id) vì tôi muốn biết chính xác page_view nào được quy cho lượt truy cập, tôi đã thêm liên kết đó. Tôi vật lộn với nó một chút, nhưng tôi nghĩ đó là quyết định đúng đắn
cgmckeever

10

Cá nhân tôi nghiêng về việc thêm các cột vào bảng hiện có. Bảng mới không thực sự mua cho bạn bất cứ thứ gì:

  • bạn không thực sự tiết kiệm nhiều dung lượng vì các giá trị NULL trong bảng gốc không chiếm bất kỳ khoảng trống nào và bảng mới cần một số loại định danh bù đắp mọi khoản tiết kiệm nào
  • truy vấn của bạn trở nên phức tạp hơn ... where newcolumn is not nulltrở thành mộtleft outer join

Trong một bảng duy nhất, điều đó chỉ có nghĩa là kích thước hàng của bạn có thể thay đổi từ trang này sang trang khác - nhưng điều này không ảnh hưởng đến nhiều trang hiện có của bạn, đặc biệt nếu chỉ mục được nhóm của bạn nằm trên cột tăng đơn điệu (danh tính hoặc ngày / giờ).


Vì bảng hiện không rộng (dựa trên mô tả của bạn) và dữ liệu này sẽ không làm cho nó quá rộng, tôi sẽ đồng ý.
HLGEM

4

Với thông tin bạn đã cung cấp và với mục tiêu bình thường hóa chung là mục tiêu, tôi có thể chỉ cần thêm các cột không thể, nhưng bạn đã không cung cấp đủ thông tin về cách dữ liệu sẽ được sử dụng để biết cách tốt nhất để mô hình hóa dữ liệu Là.

Tùy thuộc vào cách bạn thực sự sử dụng dữ liệu này, bạn có thể muốn xem xét một mô hình dữ liệu khác. Nếu bạn đang đưa dữ liệu này để báo cáo, bạn có thể muốn xem xét một mô hình thứ nguyên, có thể hiệu quả hơn đối với một số loại báo cáo nhất định - ví dụ như phân tích thời gian trong ngày hoạt động tốt với phân chia ngày và thời gian.

Để trả lời các câu hỏi phân tích, như "thời gian phổ biến nhất trong ngày cho các lượt truy cập từ các chiến dịch như X" hoặc "ngày nào của chiến dịch chúng tôi thấy nhiều lượt truy cập nhất mỗi giờ", một cột thời gian dữ liệu sẽ không hoạt động rất tốt (nhưng điều này thậm chí có thể được phân chia theo mô hình quan hệ) và có rất nhiều trường hợp bạn có thể coi địa chỉ IP là thứ nguyên (có thể với một số loại dữ liệu địa lý trong một bông tuyết).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.