Datetime vs Timestamp trong MySQL và PHP trong thực tế?


24

Tôi không chắc chắn làm thế nào để xác định kiểu dữ liệu của mình là datetime hoặc dấu thời gian, tôi nghĩ rằng tôi sẽ cần cả hai nhưng trên các sự kiện khác nhau. Trang web của tôi bán sản phẩm và dịch vụ trên toàn thế giới và cũng có hệ thống tài khoản để người dùng đăng nhập. Hãy làm rõ những điều sau:

  • Ngày và giờ hiện tại khách hàng mua sản phẩm từ trang web của tôi: Ngày tháng?
  • Ngày và giờ giao hàng dựa trên địa điểm và ngày / giờ mua của họ, được tính từ hệ thống của chúng tôi: Thời gian?
  • Lần cuối họ đăng nhập vào tài khoản của mình: Dấu thời gian?

    1. Mã trong php để lưu trữ ngày mua (ngày hiện tại) và sau đó lưu trữ trong cơ sở dữ liệu là gì?
    2. Xin hãy giải thích cách sử dụng từng người trong số họ vì sau khi đọc nhiều lời giải thích trên internet, tôi vẫn không hiểu lắm.

Cách đây không lâu, tôi đã có một dự án lớn, trong đó hiệu suất là điều bắt buộc, sau nhiều tháng nghiên cứu, chúng tôi đã kết thúc với dấu thời gian UTC được lưu trữ trong một trường varchar, nó đã chứng minh là nhanh hơn và tốt hơn cho nhu cầu của chúng tôi (mạng xã hội lớn)
JasonDavis

Câu trả lời:


29

Dấu thời gian của MySQL :

  • Được lưu trữ trong UTC

    Chúng được chuyển đổi thành UTC trên bộ lưu trữ và được chuyển đổi trở lại múi giờ của bạn khi truy xuất. Nếu bạn thay đổi cài đặt múi giờ , các giá trị được truy xuất cũng thay đổi.

  • Có thể tự động khởi tạo và cập nhật

    Bạn có thể đặt giá trị mặc định của chúng và / hoặc giá trị cập nhật tự động thành CURRENT_TIMESTAMP

  • Có một phạm vi 1970-01-01 00:00:01 UTCđể2038-01-19 03:14:07 UTC

Trong khi đó, datetime của MySQL :

  • Những gì bạn lưu trữ là những gì bạn nhận được ™.

  • Có một phạm vi 1000-01-01 00:00:00để9999-12-31 23:59:59

    Các giá trị ngoài phạm vi có thể hoạt động - nhưng chỉ các giá trị trong phạm vi được đảm bảo hoạt động.

  • Bạn có thể lưu trữ ngày mà ngày hoặc tháng bằng không.

    Đây là cách lưu trữ sinh nhật của MySQL! Bạn không thể làm điều đó với a TIMESTAMP, với ngoại lệ duy nhất là giá trị 0 của 0000-00-00.

  • Bạn có thể lưu trữ ngày không hợp lệ, nếu bạn cần chúng, trong chế độ ALLOW_INVALID_DATE .

  • Bạn có thể đặt giá trị mặc định NOW()trong một số trường hợp, nhưng cách tự động và ngày cập nhật tự động hơn và tự nhiên hơn là TIMESTAMP.

Và tất nhiên cũng có DATETIME, hoạt động giống như vậy DATETIME, nhưng tất nhiên DATEkhông quan tâm đến thời gian và TIMEkhông quan tâm đến ngày. Tất cả bốn loại dữ liệu hoạt động hoàn hảo với một loạt các hàm ngày và thời gian , nhưng khi bạn trộn các loại dữ liệu, bạn nên biết về các hiệu ứng chuyển đổi .

Bây giờ, cho câu hỏi của bạn: Bạn nên sử dụng DATETIMEở mọi nơi. Không phải vì lý do kỹ thuật, nhưng vì bạn vẫn chưa rõ về cách thức hoạt động của MySQL, DATETIMEnên sự lựa chọn đơn giản hơn. Điều này có nghĩa là bạn sẽ phải tính toán dấu thời gian hiện tại trong PHP trước khi lưu trữ, điều đó dễ như:

$mysqldate = date("Y-m-d H:i:s"); 

Hàm ngày của PHP hoạt động như sau:

string date ( string $format [, int $timestamp = time() ] )

Các "Y-m-d H:i:s"định dạng là một trong những phù hợp với MySQL và bằng cách để lại tham số thứ hai trống rỗng, date()gọi time()để có được những hiện UNIX timestamp .

Sử dụng TIMESTAMPthay vì a DATETIMEcó giá trị gia tăng của MySQL đảm nhận trách nhiệm quyết định dấu thời gian hiện tại và bạn có thể bỏ qua trường khi bạn đang chèn / cập nhật. Nhưng vì bạn đã gửi một truy vấn và mã để lấy dấu thời gian hiện tại trong PHP là tối thiểu, bạn có thể đi theo DATETIMEmọi thứ một cách an toàn .

Đối với mã thực tế để lưu dấu thời gian PHP vào cơ sở dữ liệu, bạn nên xem các Đối tượng dữ liệu PHP và nếu bạn vẫn chưa rõ ràng, hãy hỏi StackOverflow thay thế. Nhưng đã có gần 1,5k câu hỏi liên quan rồi, hãy chắc chắn rằng bạn lướt qua chúng trước khi hỏi. Chỉ cần một gợi ý, tuyên bố chuẩn bị là cách những đứa trẻ mát mẻ làm điều đó.


Hmm, đó có thể là một vấn đề về cách bạn gửi truy vấn tới MySQL hoặc trong cấu trúc bảng của bạn ... StackOverflow là nơi tốt hơn cho các loại vấn đề này, gửi câu hỏi ở đó với cấu trúc bảng và mã php đầy đủ của bạn và một số chi tiết về vấn đề là gì và những gì bạn đã thử. Chúng tôi không thực sự thảo luận về các chi tiết cụ thể ở đây ...
yannis

Cảm ơn vì đã trả lời. Tôi đã thử sử dụng $ mysqldate = date ("Ymd H: i: s"); $ query = INSERT INTO bảng VALUE ('". $ mysqldate."') trên mã php của tôi nhưng nó sẽ được giữ trong MySQL dưới dạng 0000-00-00 00:00:00 trong ngày (trường) - Datetime (datatype). Tôi dự định lưu trữ Ngày và Giờ hiện tại. Nếu tôi đặt kiểu dữ liệu là Dấu thời gian trong cơ sở dữ liệu, làm thế nào để mã bằng php?
Mô-đun

Hiện tại tôi không được phép đăng bất kỳ bình luận nào về Stackoverflow. Nghe có vẻ hơi xấu hổ nhưng đó là cách họ đã làm với tôi.
Mô-đun

Tôi xin lỗi vì điều đó, nhưng nếu bạn đang ở chế độ treo tạm thời thì phải có lý do chính đáng. Bây giờ một lỗi có thể xảy ra trong mã trong nhận xét của bạn là bạn đang đặt tên trường là Date, đó là một từ dành riêng cho DATEkiểu dữ liệu và những điều kỳ lạ có thể xảy ra (tùy thuộc vào phiên bản MySQL), vì vậy hãy thử đổi tên nó thành một cái gì đó như creationdatevà xem điều gì xảy ra . Ngoài ra, từ PHP bạn nên coi TIMESTAMPcác trường giống như DATETIMEcác trường, điều đó thực sự không quan trọng. Định dạng của họ là như nhau.
yannis

Cảm ơn rất nhiều. Bây giờ nó đã được sắp xếp sau khi dành gần như cả đêm để tìm hiểu tại sao. :)
Mô-đun

2

Tài liệu tham khảo lấy từ Điều này:

Sự khác biệt chính:

TIMESTAMP được sử dụng để theo dõi các thay đổi đối với các bản ghi và cập nhật mỗi khi bản ghi được thay đổi. DATETIME được sử dụng để lưu trữ giá trị cụ thể và tĩnh không bị ảnh hưởng bởi bất kỳ thay đổi nào trong hồ sơ.

TIMESTAMP cũng bị ảnh hưởng bởi các cài đặt liên quan đến TIME ZONE khác nhau. Dữ liệu không đổi.

TIMESTAMP đã chuyển đổi nội bộ múi giờ hiện tại sang UTC để lưu trữ và trong quá trình truy xuất được chuyển đổi trở lại múi giờ hiện tại. Cơ sở dữ liệu không thể làm điều này.

Phạm vi được hỗ trợ của TIMESTAMP: '1970-01-01 00:00:01 UTC đến' 2038-01-19 03:14:07 range Phạm vi được hỗ trợ của UTC DATETIME: '1000-01-01 00:00:00 đến' 9999 -12-31 23:59:59


1
Vậy trong năm 2040, bạn sẽ sử dụng những gì để thay đổi hồ sơ, Dấu thời gian? Tôi đoán là không.
Bsienn

-1

Vâng, tôi nhìn vào điều này theo cách rất đơn giản. Trong trường hợp của bạn, tôi sẽ sử dụng cả hai datetimetimestamp. Với việc sử dụng cả hai bạn sẽ không có thêm bất kỳ vấn đề nào với việc lưu trữ dữ liệu hoặc những thứ tương tự. Một trường bổ sung (cột) trong bảng của bạn cũng không phải là vấn đề lớn.

Vì vậy, theo quan điểm và kinh nghiệm của tôi cho đến nay tôi thường sử dụng cả hai. Khi bạn muốn hiển thị một ngày cho khách truy cập của bạn hoặc làm cho nó dễ hiểu đối với khách truy cập, sau đó hiển thị một ngày ở định dạng datetime.

Định dạng ngày tháng có thể là một nỗi đau khi bạn muốn tính toán một cái gì đó (chênh lệch giữa 2 ngày, lấy ngày hôm qua từ ngày hiện tại, nhận 1 tuần trước từ ngày hiện tại, ngày mai hoặc một cái gì đó tương tự.) Nó không thực sự khó khăn nhưng bạn sẽ thường cần phải chuyển đổi chúng trong timestampvà sau đó làm công cụ. Và có thời gian hiện tại ví dụ bạn nhận được với: $current = date("Y-m-d");hoặc $current = date("Y-m-d H:i:s");nếu bạn cũng muốn giờ, phút và giây.

Dấu thời gian chỉ dài 11 chữ số không thực sự "có nghĩa" gì. Khi bạn nhìn vào nó, bạn sẽ không biết nó đại diện cho ngày nào. Vì vậy, nó không thực sự thân thiện với người dùng và bạn không thể sử dụng nó để chỉ lặp lại và hiển thị nó cho khách truy cập của bạn chẳng hạn. Bạn sẽ cần phải "biến đổi" nó thành thứ gì đó có thể đọc được. Nhưng nó cũng cung cấp cho bạn khả năng dễ dàng chuyển đổi nó và tính toán các ngày khác nhau. Ví dụ: nếu bạn muốn lấy dấu thời gian cho ngày mai đồng thời bạn chỉ cần thêm số giây vào ngày hiện tại và bạn có dấu thời gian vào ngày mai. Ví dụ: $tomorrow = time()+24*3600;Bạn cũng có thể dễ dàng nhận được sự khác biệt giữa hai ngày tính bằng giây hoặc bất cứ điều gì tương tự.

Vì vậy, tôi sẽ đề nghị sử dụng cả datetime và dấu thời gian. Ngay cả khi bạn sử dụng ví dụ PhpMyadmin và muốn xem nhanh một số dữ liệu, bạn sẽ thấy dễ dàng hơn khi bạn thấy một ngày ở định dạng ngày giờ (ví dụ 2011-12-20 10:15:20:) như nếu bạn chỉ nhìn vào số 11 chữ số. Vì vậy, sử dụng cả hai và sau đó gọi và sử dụng một trong đó phù hợp với bạn tốt hơn.

Nếu bạn phải hoặc muốn chọn chỉ một tôi sẽ đề xuất dấu thời gian nếu không sử dụng cả hai.


1
-1 Timestamp is just a number 11 digit long which doesn't really "mean" anythingDấu thời gian MySQL được lưu trữ ở cùng định dạng với datetime. Bạn cũng cần chuyển đổi chúng thành dấu thời gian php, để thực hiện các phép tính mà bạn mô tả, HOẶC chỉ cần sử dụng nhiều hàm ngày / giờ của MySQL và thực hiện các phép tính trong cơ sở dữ liệu. Câu trả lời của bạn không thực sự có ý nghĩa.
yannis
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.