Các thực tiễn tốt nhất xung quanh các cột cơ sở dữ liệu đã lỗi thời là gì? [đóng cửa]


14

Tôi đang thiết kế một ứng dụng sẽ ở giai đoạn đầu thu thập dữ liệu A, B và C từ khách hàng, nhưng sau đó sẽ thay vào đó thu thập dữ liệu A, B và D.

A, B, C và D đang rất liên quan và ngay bây giờ tồn tại như cột của một bảng cơ sở dữ liệu PostgreSQL đơn T .

Khi C không còn cần thiết, tôi muốn xóa tham chiếu khỏi ứng dụng của mình (tôi sử dụng Django ORM ), nhưng tôi muốn giữ dữ liệu đã được nhập. Cách tốt nhất để làm như vậy là gì?

Tôi đã nghĩ đến việc tạo một bảng mới cho ABD, nhưng điều đó có nghĩa là có thể gây ra sự cố với bất kỳ bảng tham chiếu hàng T.

Tôi chỉ có thể để cột C dọc theo và xóa các tham chiếu đến nó trong mã, cho phép dữ liệu hiện có tồn tại.

Có một lựa chọn tốt hơn mà tôi không nhìn thấy?

Một số chi tiết bổ sung:

Số lượng hàng sẽ không lớn, nhiều khả năng là 1-2 cho mỗi người dùng. Đây là một ứng dụng thị trường đại chúng, nhưng khi tôi chuyển từ C sang D, cơ sở người dùng sẽ không quá lớn. C và D có thể sẽ không được thu thập cùng một lúc, mặc dù đó là một khả năng. C và D có thể đại diện cho nhiều cột mỗi cột, không chỉ một cột.


Tôi nghĩ rằng cách chính xác để tiếp cận điều này phụ thuộc vào việc bạn có cần phân biệt giữa các hàng đã được thu thập từ {A, B, C} và các hàng được thu thập từ {A, B, D} hay không, nếu có, nếu dữ liệu hiện tại của bạn mô hình cho phép điều này. Và nó cũng sẽ phụ thuộc vào những gì bạn sẽ làm với những hàng được thu thập từ {A, B, C} - phiên bản mới của ứng dụng hiển thị chúng là {A, B, D} với "D" trống, nhưng a Người dùng không thấy nội dung của cột C, anh ta có thể muốn xóa hàng đó khỏi db (nếu ứng dụng cho phép xóa các hàng), vì anh ta không nhìn thấy nội dung.
Doc Brown


Có bao giờ có hàng nào có C và D được thu thập cùng một lúc không? Hay nó sẽ luôn là A, B, C, Null hoặc A, B, Null, D? Nếu bạn có C, D trên cùng một hàng trong một khoảng thời gian ngắn ... lý do cho việc không có bảng A, B, C và A, B, D là gì? Có phải chúng ta đang nói ... hàng trăm hàng dữ liệu? Hàng triệu? tiền tỷ? Là thời gian đáp ứng là một yếu tố? Rất nhiều chi tiết làm cho mỗi tình huống trở nên độc đáo ...
WernerCD

@WernerCD đã thêm một số chi tiết về trường hợp của tôi trong câu hỏi
Jad S

Hoặc bạn sử dụng cột hoặc bạn không. Sử dụng nó, giữ nó. Đừng, thả nó xuống. Nếu bạn muốn giữ dữ liệu xung quanh, hãy di chuyển nó sang một bảng khác (không ràng buộc khóa ngoài) hoặc xuất.
Thaylon

Câu trả lời:


31

Nếu bạn muốn giữ dữ liệu, thì nó không bị lỗi thời. Chỉ cần để nó ở nơi đó. Thật tốt nếu một số lớp được ánh xạ tới một bảng không ánh xạ mỗi cột.


1
bạn có thể kết thúc với rất nhiều cột rỗng sau một thời gian
Ewan

8
có lẽ họ có thể yêu cầu một cách tiếp cận thực tiễn tốt nhất trên stackexchange .... khi điều đó xảy ra
Ewan

8
Tôi đoán sự khó chịu của tôi với loại câu trả lời này là, chắc chắn bạn có thể thoát khỏi nó, nhưng nợ công nghệ của nó. Cuối cùng, bạn muốn có một giải pháp thực sự và không phải giải thích cho tất cả các nhân viên mới tại sao công ty công nghệ tốt nhất hiện nay của bạn có các cột ngẫu nhiên được sử dụng rải rác trong db của bạn
Ewan

1
Tôi thấy quan điểm của @Ewan, nhưng đối với trường hợp sử dụng của tôi thì điều này nên làm. Mọi thứ có thể được đơn giản hóa trong đầu tôi, nhưng sẽ khá đơn giản để chạy tập lệnh di chuyển dữ liệu sau này, nếu cần, để sao chép dữ liệu C vào một bảng mới có tham chiếu đến hàng ban đầu trong bảng T, sau đó xóa các cột C từ bảng T.
Jad S

3
@Ewan - giả sử lỗi thời cột sẽ không xảy ra chỉ một lần - nó có thể xảy ra trong vài lần, vì các yêu cầu thiết kế được phát hiện hoặc thay đổi. Nếu thay thế cho cột null là tách thành các bảng riêng biệt (ví dụ: cấu trúc thừa kế) bất cứ khi nào một cột bị lỗi thời, cơ sở dữ liệu sẽ bị lấp đầy với các bảng tham gia cho các cột lỗi thời. Tôi tin rằng điều này có khả năng kết thúc tồi tệ hơn.
Thomas W

8

OK, vì vậy, tình huống của bạn là bạn muốn các hàng cũ có thuộc tính C nhưng các hàng mới thì không.

Điều này tương đương với việc có một mối quan hệ thừa kế lớp

class All
{
    string A;
    string B;
}

class Old : All
{
    string C;
}

class New : All
{
    string D;
}

mà bạn sẽ đại diện trên cơ sở dữ liệu với ba bảng có quan hệ 1 đến 1

table All
    id varchar
    A varchar
    B varchar

table Old
    id varchar
    C  varchar

table New
    id varchar
    D  varchar

Vì vậy, bạn có thể tạo tập lệnh di chuyển để tạo bảng Cũ mới, sao chép dữ liệu id và C vào nó và xóa cột C khỏi bảng Tất cả.

Cập nhật mã của bạn theo yêu cầu với sql mới;

Ngoài ra, nếu bạn chỉ cần có thể truy vấn dữ liệu C cũ, bạn có thể tạo bảng Lưu trữ mới với A, B, C sao chép tất cả dữ liệu và xóa cột C, thêm D col vào bảng 'Live' của bạn


1
Nếu tôi chia bảng, tôi muốn lấy ba trong số chúng: {A, B} {C} {D}
Aconcagua

Điều đó không phù hợp với ví dụ?
Ewan

chờ đợi. tôi nhớ đọc
Ewan

2

Nếu lưu trữ dữ liệu có thể là một mối quan tâm, thì hãy chia các bảng: key / A / B key / C key / D

Bạn có thể thực hiện truy cập thông qua chế độ xem (định nghĩa vị trí dữ liệu trong db) hoặc thông qua thay đổi định nghĩa ORM.

Đây không phải là hoạt động hiệu quả nhất (tham gia có liên quan), nhưng nó có thể trình bày bất kỳ sự kết hợp A / B / C / D nào theo thời gian mà không thay đổi bộ nhớ bên dưới & tùy thuộc vào mẫu truy cập thực của bạn, nó có thể đủ.

Bạn có thể không may mắn với khả năng mất thời gian chết, cơ cấu lại các bảng, vv trong một hệ thống sản xuất.

Thực hiện truy cập thông qua chế độ xem cho phép bạn chuyển từ A / B / C sang A / B / C / D sang A / B / D trong bảng bên dưới với sự thay đổi tối thiểu và không có chuyển động dữ liệu. Một khung nhìn sẽ trong suốt đối với logic đọc và nếu dbms của bạn hỗ trợ các hàm hoặc các khung nhìn có thể cập nhật thì cũng trong suốt đối với logic ghi.

Thực sự tôi nghĩ rằng quyết định của bạn sẽ phản ánh rất nhiều mối quan tâm trong thế giới thực: 1) kiểu dữ liệu C & D 2) khối lượng dữ liệu tương đối được thu thập cho C / D 3) Sự chồng chéo tương đối của dữ liệu C / D so với các mục nhập C hoặc D hoàn toàn 4) Tính sẵn sàng và thời lượng của cửa sổ thời gian ngừng hoạt động 5) DBMS Hỗ trợ cho các chế độ xem có thể cập nhật 6) Mong muốn giữ các chi tiết cấu trúc vật lý trong ORM so với làm cho nó trong suốt bằng cách hiển thị qua các chế độ xem / chức năng trong db (trong đó giống nhau cho tất cả các truy cập các ứng dụng, không chỉ là ứng dụng hiện tại)

Câu trả lời của tôi được ưu tiên cho các kiểu dữ liệu lớn / phức tạp cho (1), ít trùng lặp cho (3) và thời gian chết tối thiểu cho (4), lý tưởng là có hỗ trợ dbms tốt trong (5) và nhiều ứng dụng truy cập dữ liệu trong (6)

Nhưng không có đúng / sai đối với nhiều lựa chọn thay thế: - bắt đầu bằng A / B / C, sau đó thêm D, điều chỉnh ORM, sau đó vẫn thả cột C - bắt đầu với A / B / C / D và bỏ qua null, v.v. , xem xét giải pháp của bạn và những gì bạn biết về mục đích / vòng đời dự định của nó, thực hiện một số mô hình kích thước / khối lượng & mong muốn thay đổi mọi thứ sau này vì không phải mọi thứ sẽ biến chúng ta như mong đợi.


1

Xóa tham chiếu & mồ côi dữ liệu là một lựa chọn rủi ro thấp.

Luôn có những cách sử dụng dữ liệu 'cửa sau' không xác định có thể có hoặc không quan trọng để lộ bằng cách xóa cột.

Tùy thuộc vào nội dung của cột C, có thể có một vấn đề hiệu năng nhỏ khi DB bên trong thực hiện quét toàn bộ bảng hoặc cố gắng kéo toàn bộ bảng vào bộ nhớ trong khi tham gia nếu trình tối ưu hóa thấy điều này hiệu quả hơn so với sử dụng chỉ mục.

Các ứng dụng có thể đang đọc toàn bộ bảng một lần thay vì các cột được chọn - nhưng nếu bạn chỉ sử dụng ORM thì điều này là không thể.


1

Nhiều điều cần xem xét ở đây nhưng bạn có thể muốn xem xét việc thêm chế độ xem để phủ lên bảng thay vì trực tiếp thay đổi bảng. Theo cách đó, chỉ có quan điểm cần thay đổi.

Tôi không biết Django ORM, nhưng nó có thể là một khả năng.


2
OP cho biết họ đang sử dụng Postgres.
TripeHound

Cảm ơn - không thấy thẻ. Tôi sẽ chỉnh sửa Q.
Robbie Dee

0
  • Bạn có Bảng A với các cột a, b, c.
  • Tạo Bảng B mới với các cột a, b, d.
  • Di chuyển dữ liệu của bạn sang Bảng B.
  • Di chuyển khóa ngoại của bạn sang bảng A sang bảng B.

Bây giờ bạn có thể sử dụng Bảng B và bạn vẫn có dữ liệu cũ để tham khảo.

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.