2011-01-21 32 views
21

vì vậy chúng tôi đã thảo luận lập trình này trên Freenode và câu hỏi này xuất hiện khi tôi đang cố gắng sử dụng VARCHAR (255) để lưu Biến ngày theo định dạng sau: D/MM/YYYY. Vì vậy, câu hỏi là tại sao nó là xấu như vậy để sử dụng VARCHAR để lưu trữ ngày. Cô ấy là những lợi thế:Khi sử dụng VARCHAR và DATE/DATETIME

  1. Mã của nó nhanh hơn. Trước đây tôi đã sử dụng DATE, nhưng định dạng ngày là một nỗi đau thực sự.
  2. Sức mạnh của nó đói hơn khi sử dụng chuỗi hơn Ngày? Ai quan tâm, chúng ta sống trong thời đại Ghz.
  3. nó không đạo đức đúng (lolwut?) Đây là những gì người dùng khác nói với tôi ...

Vì vậy, những gì bạn muốn sử dụng để lưu trữ một ngày? SQL VARCHAR hoặc SQL DATE?

+2

Câu hỏi về stackoverflow.com Tôi nghĩ rằng –

+1

Người bỏ phiếu xuống: Nó sẽ giúp người hỏi nếu bạn để lại lý do * tại sao * bạn không thích câu hỏi. – Kramii

+2

Thực tế các câu trả lời có thể xuất hiện rõ ràng đối với các lập trình viên chuyên gia và rằng giai điệu là rant-ish không làm cho nó trở thành một câu hỏi hoàn toàn hợp pháp. Ngoài ra, nó tạo ra câu trả lời tốt, thông tin. Đã bỏ phiếu vì nó không xứng đáng với một điểm số âm. – cbrandolino

Trả lời

11

Khi bạn sẽ có cơ sở dữ liệu với hơn 2-3 triệu hàng bạn sẽ biết tại sao nó tốt hơn để sử dụng DATETIME hơn VARCHAR :)

câu trả lời đơn giản là với cơ sở dữ liệu - sức mạnh xử lý không phải là một vấn đề nữa không. Chỉ kích thước cơ sở dữ liệu là do thời gian tìm kiếm của HDD.

Về cơ bản với ổ cứng hiện đại, bạn có thể đọc khoảng 100 hồ sơ/giây nếu họ đang đọc theo thứ tự ngẫu nhiên (thường là trường hợp) vì vậy bạn phải làm tất cả mọi thứ bạn có thể để giảm thiểu kích thước DB, bởi vì:

  • Các người đứng đầu HDD sẽ không phải "du lịch" nhiều
  • này bạn sẽ phù hợp với dữ liệu hơn trong RAM

cuối cùng nó luôn luôn HDD của thời gian tìm kiếm mà sẽ giết bạn. Ví dụ. một số truy vấn GROUP BY đơn giản với nhiều hàng có thể mất một vài giờ khi thực hiện trên đĩa so với vài giây khi thực hiện trong RAM => vì thời gian tìm kiếm.

Đối với VARCHAR, bạn không thể thực hiện bất kỳ tìm kiếm nào. Nếu bạn ghét cách SQL xử lý các ngày quá nhiều, chỉ cần sử dụng dấu thời gian unix trong trường số nguyên 32 bit. Bạn sẽ có (về cơ bản) tất cả các ưu điểm của việc sử dụng trường SQL DATE, bạn sẽ chỉ phải thao tác và định dạng các ngày bằng cách sử dụng ngôn ngữ lập trình được chọn của bạn, chứ không phải các hàm SQL.

+2

Tất nhiên, nếu bạn đang lưu trữ nó trong một trường số nguyên 32 bit, bạn cũng cần phải nhận thức được [vấn đề Năm 2038] (https://en.wikipedia.org/wiki/Year_2038_problem). – Powerlord

+0

Cảm ơn ý tưởng về thời đại, thao tác ngày khiến tôi mất trí :) –

4

Có hai lý do:

  • kết quả Phân loại theo ngày
  • Không nhạy cảm với định dạng ngày tháng thay đổi

Vì vậy, chúng ta hãy xem ví dụ một bộ hồ sơ mà trông như thế này:

5/12/1999 | Frank N Stein 
1/22/2005 | Drake U. La 
10/4/1962 | Goul Friend 

Nếu chúng tôi lưu trữ dữ liệu theo cách của bạn, nhưng được sắp xếp vào các ngày theo thứ tự tăng dần o rder SQL sẽ trả lời với resultset trông như thế này:

1/22/2005 | Drake U. La 
10/4/1962 | Goul Friend 
5/12/1999 | Frank N. Stein 

đâu nếu chúng ta lưu trữ ngày như một DATETIME, SQL sẽ trả lời một cách chính xác ra lệnh cho họ như thế này:

10/4/1962 | Goul Friend 
5/12/1999 | Frank N. Stein 
1/22/2005 | Drake U. La 

Ngoài ra, nếu ở đâu đó xuống con đường bạn cần để hiển thị ngày ở định dạng khác, ví dụ như YYYY-MM-DD, thì bạn sẽ cần phải chuyển đổi tất cả dữ liệu của mình hoặc xử lý nội dung hỗn hợp. Khi nó được lưu trữ như là một NGÀY SQL, bạn buộc phải thực hiện chuyển đổi trong mã, và rất có thể có một chỗ để thay đổi định dạng để hiển thị tất cả các ngày - miễn phí.

+0

Xem câu trả lời của tôi về ISO 8601 bên dưới. –

34

Tại sao không đặt ốc vít bằng búa?

Vì đây không phải là công cụ thích hợp cho công việc.

Một số trong những nhược điểm của phiên bản VARCHAR:

  • Bạn không thể dễ dàng thêm/trừ ngày lên phiên bản VARCHAR.
  • Khó lấy chỉ tháng/năm.
  • Không có gì ngăn bạn đặt dữ liệu không có ngày tháng vào cột VARCHAR trong cơ sở dữ liệu.
  • Phiên bản VARCHAR là văn hóa cụ thể.
  • Bạn không thể dễ dàng sắp xếp các ngày.
  • Rất khó để thay đổi định dạng nếu bạn muốn sau này.
  • Thật độc đáo, điều này sẽ làm cho các nhà phát triển khác khó hiểu hơn.
  • Trong nhiều môi trường, việc sử dụng VARCHAR sẽ sử dụng nhiều dung lượng lưu trữ hơn. Điều này có thể không quan trọng đối với một lượng nhỏ dữ liệu, nhưng trong môi trường thương mại với hàng triệu hàng dữ liệu thì điều này cũng có thể tạo ra sự khác biệt lớn.

Tất nhiên, trong các dự án sở thích của bạn, bạn có thể làm những gì bạn muốn. Trong một môi trường chuyên nghiệp, tôi nhấn mạnh vào việc sử dụng đúng công cụ cho công việc.

+1

Trên thực tế, các ốc vít rất hữu ích đôi khi ... –

+4

Tua vít dùng để tháo ốc ra ... – Matt

+0

@ Dercsár: Thật vậy. Và có những dịp khi đặt ngày trong VARCAR cũng hữu ích. Nhưng nó thường không được khuyến khích. – Kramii

1

Giữa DATE/DATETIMEVARCHAR cho những ngày tôi sẽ đi với DATE/DATETIME mọi lúc. Nhưng có một lựa chọn thứ ba bỏ qua. Lưu trữ nó như là một INTEGER unsigned!

Tôi quyết định đi với INTEGER unsigned trong dự án cuối cùng của mình và tôi thực sự hài lòng với lựa chọn đó thay vì lưu trữ nó dưới dạng DATE/DATETIME. Bởi vì tôi đã đi qua ngày tháng giữa khách hàng và máy chủ nên nó là loại lý tưởng để tôi sử dụng. Thay vì phải lưu trữ nó như DATE và phải chuyển đổi trở lại mỗi khi tôi chọn, tôi chỉ cần chọn nó và sử dụng nó tuy nhiên tôi muốn nó. Nếu bạn muốn chọn ngày là ngày "có thể đọc được", bạn có thể sử dụng hàm FROM_UNIXTIME().

Cũng một số nguyên chiếm 4 byte trong khi DATETIME chiếm 8 byte. Tiết kiệm 50% dung lượng lưu trữ.

Sự cố sắp xếp mà Berin đề xuất cũng được giải quyết bằng cách sử dụng số nguyên làm bộ nhớ cho ngày.

+1

Xin lưu ý rằng một kiểu dữ liệu datetime là một số nguyên (hai, thực sự): ngoài cùng bên trái là số ngày kể từ kỷ nguyên, bên phải là số mili giây kể từ ngày bắt đầu (00:00: 00.000). Kỷ nguyên (zero-point trong lịch-nói) của Calandar SQL Server là 1 tháng 1 1900 00: 00: 00.000 — đây là lý do tại sao 'chuyển đổi (datetime, '')' mang lại giá trị datetime của 1 tháng 1 năm 1900. –

3

Tôi muốn bỏ phiếu cho việc sử dụng các loại ngày/giờ, chỉ vì mục đích đơn giản/nhất quán.

Nếu bạn làm lưu nó như một chuỗi ký tự, lưu nó trong ISO 8601 định dạng:

Trong số những thứ khác, ISO 8601 ngày/giờ chuỗi (A) đối chiếu đúng, (B) là con người có thể đọc được, (C) là ngôn ngữ-indepedent, và (D) là dễ dàng chuyển đổi sang các định dạng khác. Để cũi từ lời giới thiệu ISO, ISO 8601 chuỗi cung cấp

cơ quan đại diện cho những điều sau đây:

  • ngày
  • Thời gian trong ngày
  • phối hợp thời gian phổ quát (UTC)
  • Giờ địa phương có bù đắp cho UTC
  • Ngày và giờ
  • Khoảng thời gian
  • định kỳ thời gian khoảng

Cơ quan đại diện có thể ở một trong hai định dạng: một định dạng cơ bản mà có một số lượng tối thiểu của các nhân vật và một định dạng mở rộng có thêm nhân vật để tăng cường khả năng đọc của con người. Ví dụ: ngày 3 tháng 1 năm 2003 có thể được trình bày dưới dạng 20030103 hoặc 2003-01-03.

[và]

phục vụ những ưu điểm sau so với nhiều địa phương sử dụng đại diện:

  • một cách dễ dàng có thể đọc và ghi được bởi hệ thống
  • Dễ dàng so sánh và sắp xếp được
  • Ngôn ngữ độc lập
  • Các đơn vị lớn hơn được viết trước các đơn vị nhỏ hơn
  • Đối với hầu hết đại diện các ký hiệu là ngắn và có độ dài không đổi

Một điều cuối cùng: Nếu tất cả các bạn cần làm là lưu trữ một ngày, sau đó lưu trữ nó trong các tiêu chuẩn ISO 8601 hình thức ngắn YYYYMMDD trong một char (8) cột không có dung lượng lưu trữ nhiều hơn giá trị ngày giờ (và bạn không cần phải lo lắng về khoảng cách 3 mili giây giữa dấu tick cuối cùng của một ngày và dấu tick đầu tiên của ngày tiếp theo. Nhưng đó là vấn đề cho một cuộc thảo luận khác. Nếu bạn chia nhỏ thành 3 cột — YYYY char(4), MM char(2), DD char(2) bạn sẽ sử dụng cùng một lượng bộ nhớ và có thêm tùy chọn để lập chỉ mục. Thậm chí tốt hơn, lưu trữ các lĩnh vực như một đoạn ngắn cho yyyy (4 byte), và một tinyint cho mỗi MM và DD — bây giờ bạn đang xuống đến 6 byte cho ngày. Hạn chế, tất nhiên, để phân hủy các thành phần ngày vào các bộ phận cấu thành của chúng là việc chuyển đổi sang các kiểu dữ liệu ngày/giờ thích hợp là phức tạp.

Các vấn đề liên quan