Hai trường cơ sở dữ liệu cho ngày và thời gian - chúng có nên được hợp nhất không?


8

Trong câu hỏi sau đây, tên trường và bảng đã được thay đổi để bảo vệ danh tính của chúng.

Nếu tôi có hai cột cơ sở dữ liệu:

MONKEY_DATE DATETIME NULL (with data e.g. 2012-05-14 00:00:00.000)
MONKEY_TIME DATETIME NULL (with data e.g. 1753-01-01 16:30:53.025)

Thành phần ngày của trường thời gian hầu hết được đặt thành ngày 1 tháng 1 năm 1753 ... nhưng một số dữ liệu có ngày 1 tháng 1 năm 1899 và một số có ngày 1 tháng 1 năm 1900.

Tôi thấy rằng việc duy trì mã để truy vấn và báo cáo về các cột này khiến tôi (và nhóm của chúng tôi) đau đầu có thể dễ dàng giải quyết bằng cách hợp nhất hai cột. Tuy nhiên, kinh nghiệm (và Terry Goodkind ) đã dạy tôi rằng không có gì là dễ dàng. Xem bên dưới một số ví dụ về lý do tại sao điều này là đau đầu.

Cách tiếp cận của tôi

Tôi nghĩ cách tiếp cận sau đây sẽ có hiệu quả mong muốn của việc hợp nhất hai cột:

  1. Sử dụng SQL để cập nhật dữ liệu, đặt giá trị cho trường ngày và giá trị cho trường thời gian cả hai thành cùng một giá trị, là sự pha trộn của thành phần ngày từ trường ngày và thành phần thời gian từ trường thời gian
  2. Viết bất kỳ mã mới chỉ sử dụng trường MONKEY_DATE
  3. Cuối cùng loại bỏ trường MONKEY_TIME và bất kỳ SQL thành phần ngày / giờ nào (xem ví dụ)
  4. Thả MONKEY_TIME

Điều này có nghĩa là chúng ta không cần phải ngay lập tức thực hiện các thay đổi hồi cứu cho toàn bộ hệ thống ... tất cả các mã hiện có sẽ tiếp tục hoạt động ... và chúng ta có thể bắt đầu thực hiện mọi thứ theo cách đúng đắn.

SQL cho # 1 có thể là (Oracle):

UPDATE MONKEY SET 
    MONKEY_DATE = TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
                      TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
                      'MM/DD/YYYY HH24:MI:SS')
    MONKEY_TIME = TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
                      TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
                      'MM/DD/YYYY HH24:MI:SS')

Câu hỏi

Câu hỏi của tôi cho bạn là:

  • Những lĩnh vực này có nên được sáp nhập?
  • Cách tiếp cận của tôi có hợp lý để hợp nhất hai cột này không?
  • Bạn có nghĩ rằng sẽ tốt hơn nếu bỏ qua bước hai và ba?
  • Bạn có bất kỳ ý kiến ​​hoặc đề xuất (xây dựng) khác?

Ví dụ

Ví dụ: để chọn tất cả ngày và giờ khỉ của tôi và sắp xếp chúng theo ngày và giờ, tôi cần phải làm một cái gì đó như thế này (SQL Server):

SELECT 
      CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_DATE, 101), 101) AS MONKEY_DATE
    , CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_TIME, 108), 108) AS MONKEY_TIME 
FROM MONKEY 
ORDER BY
      CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_DATE, 101), 101) DESC
    , CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_TIME, 108), 108) DESC

hoặc cái này (Oracle - rõ ràng hơn một chút):

SELECT
      TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY'), 'MM/DD/YYYY') AS MONKEY_DATE
    , TO_DATE(TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 'HH24:MI:SS') AS MONKEY_TIME
FROM MONKEY
ORDER BY
      TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY'), 'MM/DD/YYYY') DESC
    , TO_DATE(TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 'HH24:MI:SS') DESC

Tôi cũng thường thấy mình chọn cột ngày / giờ hợp nhất (Oracle):

SELECT 
    TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
            TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
        'MM/DD/YYYY HH24:MI:SS') AS MONKEY_DATE_TIME 
FROM MONKEY

Bởi vì, hầu như tất cả thời gian, chúng tôi muốn biết ngày và giờ của con khỉ.

SQL trên có thể dễ dàng được thay đổi thành:

SELECT MONKEY_DATE_TIME FROM MONKEY ORDER BY MONKEY_DATE_TIME

... Giá như chúng ta đã hợp nhất các cột.

Lý lịch

Tôi đã thừa hưởng một hệ thống ASP cũ lưu trữ ngày và giờ trong các cột riêng biệt trong cơ sở dữ liệu. Tôi được cho biết điều này có lẽ là do ứng dụng đã khởi động trong phiên bản đầu tiên của Access, nơi không thể lưu trữ cả ngày và giờ trong cùng một cột. Các whys và hows không thực sự là một phần của câu hỏi này, nhưng một số người muốn biết.

PS

Tôi thực sự gần như đã đăng bài này trên SO.SE, vì vậy tôi xin lỗi nếu tôi nhận được trang web sai.


Cam kết hợp nhất. Sau khi cam kết - cắt!
Oded

Câu trả lời:


15

Một điểm nhỏ: KHI bạn hợp nhất hai cột, bạn có thể muốn thực hiện hợp nhất vào cột "MONKEY_DATE_2" mới thay vì ghi đè lên cột hiện có. Điều đó làm cho các cột hiện tại của bạn không thay đổi và bạn có thể tìm thấy tất cả các mã chưa được cập nhật để hoạt động với cấu trúc mới với grep.


6
+1. Đó chính xác là những gì tôi sẽ đề xuất (với ngoại lệ là tôi sẽ gọi cột mới MONKEY_DATETIME).
Doc Brown

5
Và đừng quên thêm các kích hoạt cập nhật các cột cũ khi cột mới thay đổi và ngược lại.
Blrfl

Ừm Vâng. Gây nên. Ít nhất là cho đến khi chiếc rìu rơi xuống ... :)
mjfgates

7

Vâng, tôi nghĩ rằng họ nên được sáp nhập. Tôi thường không bận tâm đến việc tách các trường ngày và thời gian trừ khi có lý do chính đáng để làm điều đó. Các hệ thống cũ có thể là một lý do chính đáng nhưng nếu dữ liệu đã được di chuyển sang một hệ thống có thể xử lý ngày và thời gian kết hợp, thì việc hợp nhất là một ý tưởng tốt.

Đối với cách tiếp cận của bạn, nó có vẻ hợp lý. Bạn thậm chí có thể muốn chạy một dự án tái cấu trúc nhỏ để sửa tất cả mã cùng một lúc để đảm bảo rằng tất cả các truy vấn của bạn được sửa cùng nhau để thoát khỏi "Cuối cùng loại bỏ trường MONKEY_TIME", mặc dù có thể mất một thời gian và nó có thể sẽ yêu cầu thử nghiệm hồi quy đáng kể. Đó không phải là một vấn đề nếu bạn có kế hoạch trước cho nó.

Đồng thời điều tra xem có bất kỳ hệ thống hạ nguồn nào (như dịch vụ web hoặc hệ thống báo cáo bên ngoài) được xây dựng từ các cơ sở mã khác nhau nhưng vẫn phụ thuộc vào các giá trị ngày và giờ riêng biệt. Nếu các hệ thống như vậy tồn tại, chúng cũng sẽ phải là một phần của kế hoạch này.


1
+1 cho các hệ thống hạ nguồn. Chúng tôi có một vài API cần được kiểm tra ... Hmm và nó có thể ảnh hưởng đến các hệ thống của bên thứ ba sử dụng API. Tôi sẽ phải suy nghĩ về điều đó, cảm ơn.
oliver-clare

1
Haha. Cả hai câu trả lời đều có "Đối với * của bạn, nghe có vẻ hợp lý". Tư tưởng lớn gặp nhau? : P
Oleksi

Nếu hệ thống kế thừa về cơ bản vẫn được giữ nguyên, hãy chắc chắn kiểm tra mã tham chiếu các ngày đó được gói phù hợp để chỉ tham chiếu ngày hoặc chỉ thời gian khi thích hợp.
mikebabcock

3

Nếu ngày và thời gian luôn được sử dụng cùng nhau, thì bằng mọi cách, hãy hợp nhất các cột và gặt hái những lợi ích của ít đau đầu hơn.

Những điều cần chú ý:

  • Sử dụng cột thời gian để tính thời gian tương đối qua các ngày (ví dụ: "chọn những con khỉ đi chuối vào bất kỳ ngày nào trong một giờ trong vòng một giờ khi con khỉ này đi chuối").
  • Số học trên cột ngày không xử lý các ngày phân số một cách lành mạnh.
  • Sử dụng cột ngày làm cơ chế nhóm.

Nếu bạn có các truy vấn hiện tại đặc biệt dính, hãy tạo chế độ xem có thể cập nhật mô phỏng hành vi cũ cho đến khi bạn có thể làm cho chúng thẳng ra.


2

Tôi đã có một vấn đề tương tự ở một nhiệm kỳ công việc trước đó. Chúng tôi chia ngày và thời gian thành hai cột DB. Điều này khiến chúng tôi đau đầu. > _ <Như đã nói, tôi thực sự khuyên bạn nên chuyển sang một cột thời gian duy nhất trong DB của bạn. Điều này sẽ giữ rất nhiều lỗi từ leo lên.

Đối với chiến lược của bạn, điều này nghe có vẻ hợp lý, nhưng hãy đảm bảo bạn có được cả nhóm tham gia vào quyết định này và tái cấu trúc. Bạn cần chủ động để không khuyến khích bất cứ ai sử dụng lược đồ dữ liệu cũ.

Nếu không có nhiều thay đổi mã cần thiết (và bạn có thêm thời gian!), Bạn có thể xem xét thực hiện thay đổi tất cả cùng một lúc và không có bước "trung gian" nơi bạn hỗ trợ cả hai lược đồ dữ liệu. Tuy nhiên, điều này thường không thể xảy ra nên có lẽ bạn sẽ cần phải có một số loại kế hoạch di chuyển như kế hoạch bạn đã đề cập trong bước 2/3


1

Nếu bạn đang thực hiện thay đổi này theo thời gian (trái ngược với việc chuẩn bị tất cả các thay đổi và sau đó cài đặt mọi thứ cùng một lúc), bạn cần cẩn thận rằng bạn không đọc các giá trị theo cách mới khi nó được viết theo cách cũ. Vì vậy, quá trình chuyển đổi sẽ cần phải đi:

  1. Tất cả mới viết cả cách mới và cách cũ (sử dụng cột mới cho cách mới sẽ giúp ích) và đọc theo cách cũ. Mã hiện tại được sửa đổi để viết cả cách mới và cách cũ.

  2. Khi tất cả các mã đang viết cả hai cách, hãy chuyển đổi dữ liệu hiện có để nó có sẵn cả hai cách.

  3. Tất cả các mã mới đọc theo cách mới (và vẫn viết cả hai cách). Mã hiện tại được sửa đổi để đọc theo cách mới.

  4. Khi tất cả các mã đang đọc theo cách mới, mã mới chỉ có thể viết theo cách mới và mã hiện tại có thể được sửa đổi để chỉ viết theo cách mới.

  5. Khi tất cả các mã đang đọc và viết theo cách mới và không có mã nào tham chiếu các cột cũ, chúng có thể bị xóa.

Cách mới (một cột có cả ngày và thời gian) rõ ràng tốt hơn đối với tôi, bạn phải quyết định xem có đủ cải tiến để trải qua quá trình chuyển đổi hay không.

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.