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