首页 > Mysql > mysql中的数据存储选择

mysql中的数据存储选择

2018年5月3日 发表评论 阅读评论

MySQl中有多种表示日期和时间的数据类型。其中YEAR表示年份,DATE表示日期,TIME表示时间,DATETIME和TIMESTAMP表示日期和实践。它们的对比如下

YEAR ,字节数为1,取值范围为“1901——2155”
DATE,字节数为4,取值范围为“1000-01-01——9999-12-31”
TIME,字节数为3,取值范围为“-838:59:59——838:59:59”
DATETIME,字节数为8,取值范围为“1000-01-01 00:00:00——9999-12-31 23:59:59”
TIMESTAMP,字节数为4,取值范围为“19700101080001——20380119111407”.

以前经常看到有人说时间存储为int类型的时候查询会比timestamp类型快很多,到底有多大的差别哪?我动手测试了一下,给大家分享一下测试结果。

一、表结构

test1表为时间存储为int类型,test2表为存储为timestamp类型。

CREATE TABLE `test1` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL DEFAULT '',
  `address` varchar(100) NOT NULL DEFAULT '',
  `email` varchar(50) NOT NULL DEFAULT '',
  `created_at` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_createdat` (`created_at`),
  KEY `idx_name_time` (`name`,`created_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE `test2` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) NOT NULL DEFAULT '',
  `address` varchar(100) NOT NULL DEFAULT '',
  `email` varchar(50) NOT NULL DEFAULT '',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_createdat` (`created_at`),
  KEY `idx_name_time` (`name`,`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

 二、生成测试数据

我是自己写的python脚本,利用了python的faker库。

import faker
import time
import pymysql

def timestamp_datetime(value):
    format = '%Y-%m-%d %H:%M:%S'
    # value为传入的值为时间戳(整形),如:1332888820
    value = time.localtime(value)
    ## 经过localtime转换后变成
    ## time.struct_time(tm_year=2012, tm_mon=3, tm_mday=28, tm_hour=6, tm_min=53, tm_sec=40, tm_wday=2, tm_yday=88, tm_isdst=0)
    # 最后再经过strftime函数转换为正常日期格式。
    dt = time.strftime(format, value)
    return dt

def gen_sql(max=1000):
    sqlData = []
    i=0
    while i < max :
        name = generator.name()
        email = generator.email()
        unix_time=generator.unix_time()
        address = generator.address()
        time=timestamp_datetime(unix_time)
        sql = "INSERT INTO test1 (`name`,`address`,`email`,`created_at`) VALUE ('%s','%s','%s',%d);" % (name,address,email,unix_time)
        sql2 = "INSERT INTO test2 (`name`,`address`,`email`,`created_at`) VALUE ('%s','%s','%s','%s');" % (name,address,email,time)
        i=i+1
        sqlData.append(sql)
        sqlData.append(sql2)
    return sqlData

start_time = time.time()

generator = faker.Faker(locale="zh-cn")
total = 1000000*2
one_time=1000
times=total/one_time
print("start generating data")

conn = pymysql.connect(
    host = "127.0.0.1",
    user = "root",
    password = "123456",
    database = "sql_test",
    charset = 'utf8',
    cursorclass = pymysql.cursors.DictCursor)


cursor = conn.cursor()

i=0
while i < times:
    sql_data = gen_sql(one_time)
    for sql in sql_data:
        cursor.execute(sql)
    #commit以后更新才会提交到数据库
    conn.commit()
    i=i+1
    print("add records : %d" % (i*one_time))

cursor.close()
conn.close()
use_time=time.time()-start_time
print("done,use time:%f" % (use_time))

 三、占用空间

由于innodb的show table status from db中的值不准确,所以这里我们可以当做相等。

四、查询性能

#43ms
 select SQL_NO_CACHE * from test1 where created_at > 1025340225 limit 10; 
# 82ms
 select SQL_NO_CACHE * from test2 where created_at > '2002-06-29 16:43:45' limit 10;

单一索引查询,从结果来看差距是很大的,几乎有一倍了,但是就看这点损耗你可以接受吗?

 

分类: Mysql 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
您必须在 登录 后才能发布评论.