萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> 解析mysql TIMESTAMP(時間戳)和datetime不同之處比較

解析mysql TIMESTAMP(時間戳)和datetime不同之處比較

作者:佚名    責任編輯:admin    更新時間:    2017-05-23 18:50:29

文章來介紹了mysql TIMESTAMP(時間戳) 的一用法特性以及TIMESTAMP和datetime函數的區別與不同之處,有需要了解此函數的朋友可以參考一下本文章。

TIMESTAMP基礎知識介紹

TIMESTAMP的變體
1,TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP  在創建新記錄和修改現有記錄的時候都對這個數據列刷新

2,TIMESTAMP DEFAULT CURRENT_TIMESTAMP  在創建新記錄的時候把這個字段設置為當前時間,但以後修改時,不再刷新它

3,TIMESTAMP ON UPDATE CURRENT_TIMESTAMP  在創建新記錄的時候把這個字段設置為0,以後修改時刷新它

4,TIMESTAMP DEFAULT ‘yyyy-mm-dd hh:mm:ss’ ON UPDATE CURRENT_TIMESTAMP  在創建新記錄的時候把這個字段設置為給定值,以後修改時刷新它

MySQL目前不支持列的Default 為函數的形式,如達到你某列的默認值為當前更新日期與時間的功能,你可以使用TIMESTAMP列類型下面就詳細說明TIMESTAMP列類型

*TIMESTAMP列類型*
TIMESTAMP值可以從1970的某時的開始一直到2037年,精度為一秒,其值作為數字顯示。
TIMESTAMP值顯示尺寸的格式如下表所示:

+---------------+----------------+
| 列類型    | 顯示格式    |
| TIMESTAMP(14) | YYYYMMDDHHMMSS | 
| TIMESTAMP(12) | YYMMDDHHMMSS  |
| TIMESTAMP(10) | YYMMDDHHMM   |
| TIMESTAMP(8) | YYYYMMDD    |
| TIMESTAMP(6) | YYMMDD     |
| TIMESTAMP(4) | YYMM      |
| TIMESTAMP(2) | YY       |
+---------------+----------------+
“完整”TIMESTAMP格式是14位,但TIMESTAMP列也可以用更短的顯示尺寸創造最常見的顯示尺寸是6、8、12、和14。
你可以在創建表時指定一個任意的顯示尺寸,但是定義列長為0或比14大均會被強制定義為列長14。
列長在從1~13范圍的奇數值尺寸均被強制為下一個更大的偶數。

*列如:*
定義字段長度   強制字段長度
TIMESTAMP(0) -> TIMESTAMP(14)
TIMESTAMP(15)-> TIMESTAMP(14)
TIMESTAMP(1) -> TIMESTAMP(2)
TIMESTAMP(5) -> TIMESTAMP(6)

所有的TIMESTAMP列都有同樣的存儲大小,使用被指定的時期時間值的完整精度(14位)存儲合法的值不考慮顯示尺寸。不合法的日期,將會被強制為0存儲
*這有幾個含意: *
1、雖然你建表時定義了列TIMESTAMP(8),但在你進行數據插入與更新時TIMESTAMP列實際上保存了14位的數據(包括年月日時分秒),只不過在你進行查詢時MySQL返回給你的是8位的年月日數據。如果你使用ALTER TABLE拓寬一個狹窄的TIMESTAMP列,以前被“隱蔽”的信息將被顯示。
2、同樣,縮小一個TIMESTAMP列不會導致信息失去,除了感覺上值在顯示時,較少的信息被顯示出。
3、盡管TIMESTAMP值被存儲為完整精度,直接操作存儲值的唯一函數是UNIX_TIMESTAMP();由於MySQL返回TIMESTAMP列的列值是進過格式化後的檢索的值,這意味著你可能不能使用某些函數來操作TIMESTAMP列(例如HOUR()或SECOND()),除非TIMESTAMP值的相關部分被包含在格式化的值中。例如,一個TIMESTAMP列只有被定義為TIMESTAMP(10)以上時,TIMESTAMP列的HH部分才會被顯示,因此在更短的TIMESTAMP值上使用HOUR()會產生一個不可預知的結果。
4、不合法TIMESTAMP值被變換到適當類型的“零”值(00000000000000)。(DATETIME,DATE亦然)
*你可以使用下列語句來驗證:*
CREATE TABLE test ('id' INT (3) UNSIGNED AUTO_INCREMENT, 'date1'
TIMESTAMP (8) PRIMARY KEY('id'));
INSERT INTO test SET id = 1;
SELECT * FROM test;
+----+----------------+
| id | date1     |
+----+----------------+
| 1 | 20021114    |
+----+----------------+
ALTER TABLE test CHANGE 'date1' 'date1' TIMESTAMP(14);
SELECT * FROM test;
+----+----------------+
| id | date1     |
+----+----------------+
| 1 | 20021114093723 |
+----+----------------+

你可以使用TIMESTAMP列類型自動地用當前的日期和時間標記INSERT或UPDATE的操作。如果你有多個TIMESTAMP列,只有第一個自動更新。自動更新第一個TIMESTAMP列在下列任何條件下發生:
1、列值沒有明確地在一個INSERT或LOAD DATA INFILE語句中指定。
2、列值沒有明確地在一個UPDATE語句中指定且另外一些的列改變值。(注意一個UPDATE設置一個列為它已經有的值,這將不引起TIMESTAMP列被更新,因為如果你設置一個列為它當前的值,MySQL為了效率而忽略更改。)
3、你明確地設定TIMESTAMP列為NULL.
4、除第一個以外的TIMESTAMP列也可以設置到當前的日期和時間,只要將列設為NULL,或NOW()。
CREATE TABLE test (
'id' INT (3) UNSIGNED AUTO_INCREMENT,
'date1' TIMESTAMP (14),
'date2' TIMESTAMP (14),
PRIMARY KEY('id')
);

INSERT INTO test (id, date1, date2) VALUES (1, NULL, NULL);
INSERT INTO test SET id= 2;
+----+----------------+----------------+
| id | date1     | date2     |
+----+----------------+----------------+
| 1 | 20021114093723 | 20021114093723 |
| 2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->第一條指令因設date1、date2為NULL,所以date1、date2值均為當前時間第二條指令因沒有設date1、date2列值,第一個TIMESTAMP列date1為更新為當前時間,而二個TIMESTAMP列date2因日期不合法而變為“00000000000000”
UPDATE test SET id= 3 WHERE id=1;
+----+----------------+----------------+
| id | date1     | date2     |
+----+----------------+----------------+
| 3 | 20021114094009 | 20021114093723 |
| 2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->這條指令沒有明確地設定date2的列值,所以第一個TIMESTAMP列date1將被更新為當前時間

UPDATE test SET id= 1,date1=date1,date2=NOW() WHERE id=3;
+----+----------------+----------------+
| id | date1     | date2     |
+----+----------------+----------------+
| 1 | 20021114094009 | 20021114094320 |
| 2 | 20021114093724 | 00000000000000 |
+----+----------------+----------------+
->這條指令因設定date1=date1,所以在更新數據時date1列值並不會發生改變而因設定date2=NOW(),所以在更新數據時date2列值會被更新為當前時間此指令等效為 UPDATE test SET id= 1,date1=date1,date2=NULL WHERE id=3;
因MySQL返回的 TIMESTAMP 列為數字顯示形式,你可以用DATE_FROMAT()函數來格式化 TIMESTAMP 列
SELECT id,DATE_FORMAT(date1,'%Y-%m-%d %H:%i:%s') As date1,
DATE_FORMAT(date2,'%Y-%m-%d %H:%i:%s') As date2 FROM test;
+----+---------------------+---------------------+
| id | date1        | date2        |
+----+---------------------+---------------------+
| 1 | 2002-11-14 09:40:09 | 2002-11-14 09:43:20 |
| 2 | 2002-11-14 09:37:24 | 0000-00-00 00:00:00 |
+----+---------------------+---------------------+

SELECT id,DATE_FORMAT(date1,'%Y-%m-%d') As date1,
DATE_FORMAT(date2,'%Y-%m-%d') As date2 FROM test;

+----+-------------+-------------+
| id | date1    | date2    |
+----+-------------+-------------+
| 1 | 2002-11-14 | 2002-11-14 |
| 2 | 2002-11-14 | 0000-00-00 |
+----+-------------+-------------+

在某種程度上,你可以把一種日期類型的值賦給一個不同的日期類型的對象。然而,而尤其注意的是:值有可能發生一些改變或信息的損失:

1、如果你將一個DATE值賦給一個DATETIME或TIMESTAMP對象,結果值的時間部分被設置為'00:00:00',因為DATE值中不包含有時間信息。  
2、如果你將一個DATETIME或TIMESTAMP值賦給一個DATE對象,結果值的時間部分被刪除,因為DATE類型不存儲時間信息。
3、盡管DATETIME, DATE和TIMESTAMP值全都可以用同樣的格式集來指定,但所有類型不都有同樣的值范圍。
例如,TIMESTAMP值不能比1970早,也不能比2037晚,這意味著,一個日期例如'1968-01-01',當作為一個DATETIME或DATE值時它是合法的,但它不是一個正確TIMESTAMP值!並且如果將這樣的一個對象賦值給TIMESTAMP列,它將被變換為0。

*當指定日期值時,當心某些缺陷: *

1、允許作為字符串指定值的寬松格式能被欺騙。例如,,因為“:”分隔符的使用,值'10:11:12'可能看起來像時間值,但是如果在一個日期中使用,上下文將作為年份被解釋成'2010-11-12'。值'10:45:15'將被變換到'0000-00-00',因為'45'不是一個合法的月份。

2、以2位數字指定的年值是模糊的,因為世紀是未知的。MySQL使用下列規則解釋2位年值: 在00-69范圍的年值被變換到2000-2069。 在范圍70-99的年值被變換到1970-1999。

TIMESTAMP與datetime對比


相同

顯示

TIMESTAMP列的顯示格式與DATETIME列相同。換句話說,顯示寬度固定在19字符,並且格式為YYYY-MM-DD HH:MM:SS。

不同

范圍

datetime 以'YYYY-MM-DD HH:MM:SS'格式檢索和顯示DATETIME值。支持的范圍為'1000-01-01 00:00:00'到'9999-12-31 23:59:59'TIMESTAMP值不能早於1970或晚於2037

儲存

TIMESTAMP

1.4個字節儲存(Time stamp value is stored in 4 bytes)

2.值以UTC格式保存( it stores the number of milliseconds)

3.時區轉化 ,存儲時對當前的時區進行轉換,檢索時再轉換回當前的時區。

datetime

1.8個字節儲存(8 bytes storage)

2.實際格式儲存(Just stores what you have stored and retrieves the same thing which you have stored.)

3.與時區無關(It has nothing to deal with the TIMEZONE and Conversion.)

實例對比

現在我來做個時區對他們的影響。

1.先插入一個數據insert into `t8` values(now(), now());

2.改變客戶端時區(東9區,日本時區)。

3.再次顯示插入的數據,變化了,timestamp類型的數據 增加了 1個小時


接下來 討論一些timestamp 的其他的屬性

1.null 是否為空

timestamp 默認允許為 “非空”(not null by default), 如果你在定義“ts TIMESTAMP DEFAULT NULL” 是非法的。 可以指定為空 null ,“ts TIMESTAMP NULL" ,這時可以在添加語句改變默認值。

ts2 TIMESTAMP NULL DEFAULT 0,ts3 TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP 


default (一個表中只能有一個列選擇下面其中一種)

default CURRENT_TIMESTAMP default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
ON UPDATE CURRENT_TIMESTAMP
ON UPDATE 見上2 

MYSQL中TIMESTAMP簡單實例


MYSQL中TIMESTAMP類型可以設定默認值,就像其他類型一樣。
1、自動UPDATE 和INSERT 到當前的時間:
表:
/*DDL Information For - test.t1*/
---------------------------------

Table   Create Table                                                                        
------  -------------------------------------------------------------------------------------
t1      CREATE TABLE `t1` (                                                                 
          `p_c` int(11) NOT NULL,                                                           
          `p_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 
        ) ENGINE=InnoDB DEFAULT CHARSET=gb2312                                              


數據:

1    2007-10-08 11:53:35
2    2007-10-08 11:54:00

insert into t1(p_c) select 3;
update t1 set p_c = 2 where p_c = 2;

數據:

1    2007-10-08 11:53:35
2    2007-10-08 12:00:37
3    2007-10-08 12:00:37

2、自動INSERT 到當前時間,不過不自動UPDATE。

表:
/*DDL Information For - test.t1*/
---------------------------------

Table   Create Table                                            
------  ---------------------------------------------------------
t1      CREATE TABLE `t1` (                                     
          `p_c` int(11) NOT NULL,                               
          `p_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP 
        ) ENGINE=InnoDB DEFAULT CHARSET=gb2312                  

數據:
insert into t1(p_c) select 4;
update t1 set p_c = 3 where p_c = 3;

1    2007-10-08 11:53:35
2    2007-10-08 12:00:37
3    2007-10-08 12:00:37
4    2007-10-08 12:05:19


3、一個表中不能有兩個字段默認值是當前時間,否則就會出錯。不過其他的可以。
表:
/*DDL Information For - test.t1*/
---------------------------------

Table   Create Table                                                  
------  ---------------------------------------------------------------
t1      CREATE TABLE `t1` (                                           
          `p_c` int(11) NOT NULL,                                     
          `p_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,      
          `p_timew2` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00' 
        ) ENGINE=InnoDB DEFAULT CHARSET=gb2312                        

數據:
1    2007-10-08 11:53:35    0000-00-00 00:00:00
2    2007-10-08 12:00:37    0000-00-00 00:00:00
3    2007-10-08 12:00:37    0000-00-00 00:00:00
4    2007-10-08 12:05:19    0000-00-00 00:00:00

copyright © 萬盛學電腦網 all rights reserved