探讨:mysql 数据库存时间最好是时间戳还是格式的时间

虽然我认为讨论技术问题时,宣扬“自己的系统实际表现有多牛(所以别人也一定要这么做)”不是什么好的论调……但我必须认同一点:这个问题的权衡还真就不是从性能上考虑的时间戳和字面时间的互转只是简单的计算,所消耗的资源远远达不到引发问题的地步。

使用时间戳的唯一考虑是:你的应用是否涉及多时区,时间数据是否和时区相关。如果回答“是”,那么就必须使用时间戳,没有任何第二方案。

只有时间戳表示的时间是准确、恒定的,就连时间+日期+时区也不行——时区这玩意儿可不是恒定不变的……

其余的都不是什么重要的考虑,自己喜欢就行。

一般认为坚持使用时间戳总是好的,在程序设计中只会提供便利,不会引入坏处。至于查看数据时暴露时间戳原值,那是显示环节的不完备(或故意设计),而不是用时间戳用错了,切勿张冠李戴抹黑好东西。

日期的字符串-时间互转、计算、比较及时区转换,请使用后台语言中提供的相关类,不自己造轮子就可以。

可以略微注意:2038年问题的陷阱。对于MySQL而言,如果存时间戳请使用bigint,而尽量不要使用int;若存时间是字符串型的,建议使用TIMESTAMP或者DATETIME。

TIMESTAMP与DATETIME2者的区别:

TIMESTAMP和DATETIME的相同点:

1> 两者都可用来表示YYYY-MM-DD HH:MM:SS[.fraction]类型的日期。

 

TIMESTAMP和DATETIME的不同点:

1> 两者的存储方式不一样

对于TIMESTAMP,它把客户端插入的时间从当前时区转化为UTC(世界标准时间)进行存储。查询时,将其又转化为客户端当前时区进行返回。

而对于DATETIME,不做任何改变,基本上是原样输入和输出。

2> 两者所能存储的时间范围不一样

timestamp所能存储的时间范围为:'1970-01-01 00:00:01.000000' 到 '2038-01-19 03:14:07.999999'。

datetime所能存储的时间范围为:'1000-01-01 00:00:00.000000' 到 '9999-12-31 23:59:59.999999'。

 

总结:TIMESTAMP和DATETIME除了存储范围和存储方式不一样,没有太大区别。当然,对于跨时区的业务,TIMESTAMP更为合适。

 

https://www.cnblogs.com/mxwz/p/7520309.html

转载:http://www.360doc.com/content/16/0614/06/9200790_567583079.shtml


关注公众号,了解更多it技术(it问答网

mysql创建库,表,列指令

编写整理:徐多蔚

创建数据库:
#nihaoma就是我们的数据库名称
create database nihaoma;

#删除库
 drop database nihaoma;
#查看所有的数据库
show databases;

#设置当前要操作的数据库
use nihaoma;

#列表查看指定库下的所有的表
show tables;

#若没表,我们可以演示创建;
CREATE TABLE `obj_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(20) NOT NULL,
  `password` char(32) NOT NULL DEFAULT '',
  `addtime` datetime DEFAULT NULL COMMENT '添加时间',
  `updatetime` datetime DEFAULT NULL,
  `gid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`),
  UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM AUTO_INCREMENT=56 DEFAULT CHARSET=utf8 COMMENT='用户表';

#命令行下查看表结构
desc obj_users;

#增加字段指令 tc004_tp5为数据库名,obj_users为名
ALTER TABLE `tc004_tp5`.`obj_users`
ADD COLUMN `cs4` varchar(255) NULL DEFAULT NULL COMMENT '测试';

#注意cmd命令下若输入中文的备注,有可能会出现乱码。

#修改字段(cs4中的备注为csssss)指令
ALTER TABLE `tc004_tp5`.`obj_users`
CHANGE COLUMN `cs4` `cs4` varchar(255) NULL DEFAULT NULL COMMENT 'csssss';

#删除字段cs4指令
ALTER TABLE `tc004_tp5`.`obj_users`
  DROP COLUMN `cs4`;

#删除表
 drop table obj_users;
#增,删,改,查sql语句这里省略。
……


 


关注公众号,了解更多it技术(it问答网

sql中用临时表 或 创建视图那个效率比较快!

sql中用临时表 或 创建视图那个效率比较快!

1,存在方式:
临时存在于 服务器内存中
视图 无存在形式
2, 生命周期:
临时表 Sql服务关闭就消失
视图 你不删它就不会消失
3,用途
临时表 经常作为 中间转接层
视图 作为物理表的窗口
4,效率
临时表因为在缓存中,所以执行效率比较高
视图 效率一般,但是节省I/O操作,节约资源
5,在存储过程使用时:
临时表,效率很高{可能是数据量少,再加上临时表是在缓存中,所以执行效率高}
视图 一般

MySQL如何创建和使用临时表

CREATE TEMPORARY TABLE tmp_table SELECT * FROM table_name;

mysql中视图功能会节省SQL解析时间吗

视图功能,只是把多个表,按照自已的需求,东一块西一块,逻辑拼在一起,形成一个逻辑表。调用的时候直接操作这个逻辑表视图就可以了,其它分析解释的操作就交给mysql引擎去处理,最终查询还是要经原来的物理表的。用视图是不会节省sql执行时间的,反而会增加解析时间,减少效率的。但是视图有视图的优势!

视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。

但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。
视图有很多优点,主要表现在:

1\简化查询

3\定制数据【可以在视图中只开放部分指定的数据】

4\合并分割数据【大数据分表的时候可以用到】

视图存放:视图都放在VIEWS表里面:可以用过以下指令查看。

SELECT * FROM `information_schema`.`VIEWS`;

其他参考:https://zhidao.baidu.com/question/2119873937635607147.html?qbl=relate_question_2&word=%B1%ED%CA%D3%CD%BC%20%C4%DC%CC%E1%B8%DFsql%D0%A7%C2%CA%C2%F0


关注公众号,了解更多it技术(it问答网

ab命令做压测测试

1. 背景

互联网发达的今天,大大小小的网站如雨后春笋,不断出现,但是想要做出一个网站很简单,但是想要做好一个网站,非常非常难,首先:网站做好之后的功能怎么样这都是次要的,主要的是你的网站能承受怎么样的访问量,一个在高压访问下,能承受很高峰值的访问并发才能称得上是一个好的网站,那么作为一个程序员,当你搭建好你的网站之后,你应该怎么测试你的网站并发访问量呢?

接下来要介绍的就是apache的ab命令压测:

2.在学习使用ab命令之前,首先要了解压力测试的几个概念:(自己可以上网查下具体的概念)

  1. 吞吐率(Requests per second)
    概念:服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请求数。某个并发用户数下单位时间内能处理的最大请求数,称之为最大吞吐率。
    计算公式:总请求数 / 处理完成这些请求数所花费的时间,即
    Request per second = Complete requests / Time taken for tests
  2. 并发连接数(The number of concurrent connections)
    概念:某个时刻服务器所接受的请求数目,简单的讲,就是一个会话。
  3. 并发用户数(The number of concurrent users,Concurrency Level)
    概念:要注意区分这个概念和并发连接数之间的区别,一个用户可能同时会产生多个会话,也即连接数。
  4. 用户平均请求等待时间(Time per request)
    计算公式:处理完成所有请求数所花费的时间/ (总请求数 / 并发用户数),即
    Time per request = Time taken for tests /( Complete requests / Concurrency Level)
  5. 务器平均请求等待时间(Time per request: across all concurrent requests)
    计算公式:处理完成所有请求数所花费的时间 / 总请求数,即
    Time taken for / testsComplete requests
    可以看到,它是吞吐率的倒数。
    同时,它也=用户平均请求等待时间/并发用户数,即
    Time per request / Concurrency Level

    3.ab工具的介绍

    ab是apache自带的压力测试工具。ab非常实用,它不仅可以对apache服务器进行网站访问压力测试,也可以对或其它类型的服务器进行压力测试。比如nginx、tomcat、IIS等。
      安装:
                    1.公司应该有程序员吧,可以安装一个wamp或者phpstudy,这样apache服务器和mysql数据库都有了,一举多得。
    文件位置:打开你安装的apache的位置:找到 bin文件夹下面的ab.exe
    在该文件夹下打开命令行,输入 ab.exe -help
    对上面的Options做下解释吧:
    -n即requests,用于指定压力测试总共的执行次数。
    -c即concurrency,用于指定压力测试的并发数。
    -t即timelimit,等待响应的最大时间(单位:秒)。
    -b即windowsize,TCP发送/接收的缓冲大小(单位:字节)。
    -p即postfile,发送POST请求时需要上传的文件,此外还必须设置-T参数。
    -u即putfile,发送PUT请求时需要上传的文件,此外还必须设置-T参数。
    -T即content-type,用于设置Content-Type请求头信息,例如:application/x-www-form-urlencoded,默认值为text/plain
    -v即verbosity,指定打印帮助信息的冗余级别。
    -w以HTML表格形式打印结果。
    -i使用HEAD请求代替GET请求。
    -x插入字符串作为table标签的属性。
    -y插入字符串作为tr标签的属性。
    -z插入字符串作为td标签的属性。
    -C添加cookie信息,例如:”Apache=1234″(可以重复该参数选项以添加多个)。
    -H添加任意的请求头,例如:”Accept-Encoding: gzip”,请求头将会添加在现有的多个请求头之后(可以重复该参数选项以添加多个)。
    -A添加一个基本的网络认证信息,用户名和密码之间用英文冒号隔开。
    -P添加一个基本的代理认证信息,用户名和密码之间用英文冒号隔开。
    -X指定使用的代理服务器和端口号,例如:”126.10.10.3:88″。
    -V打印版本号并退出。
    -k使用HTTP的KeepAlive特性。
    -d不显示百分比。
    -S不显示预估和警告信息。
    -g输出结果信息到gnuplot格式的文件中。
    -e输出结果信息到CSV格式的文件中。
    -r指定接收到错误信息时不退出程序。
    -h显示用法信息,其实就是ab -help

    4.实际测试:

5.分析上面的压测结果:

Server Software: Apache/2.4.23(服务器软件名称及版本信息)

Server Hostname: 127.0.0.1(服务器主机名)

Server Port: 80 (服务器端口)

Document Path:  /a1.php (供测试的URL路径)

Document Length: 0 bytes (供测试的URL返回的文档大小)

Concurrency Level: 300 (并发数)

Time taken for tests: 19.750 seconds (压力测试消耗的总时间)

Complete requests: 300(压力测试的的总次数)

Failed requests: 0 (失败的请求数)

Total transferred: 62100 bytes (传输的总数据量)

HTML transferred: 0 bytes (HTML文档的总数据量)

Requests per second: 15.19 [#/sec] (mean) (平均每秒的请求数)

Time per request: 19749.634 [ms] (mean) (所有并发用户(这里是300)都请求一次的平均时间)

Time per request: 65.832 [ms] (mean, across all concurrent requests) (单个用户请求一次的平均时间)

Transfer rate: 3.07 [Kbytes/sec] received (传输速率,单位:KB/s)


关注公众号,了解更多it技术(it问答网

数据库sql常见优化方案

为什么要优化:
随着实际项目的启动,数据库经过一段时间的运行,最初的数据库设置,会与实际数据库运行性能会有一些差异,这时我们就需要做一个优化调整。

数据库优化这个课题较大,可分为四大类:
》服务器硬件性能:主机,内存;
》网络传输性能
》SQL语句执行性能【软件工程师】

下面列出一些数据库SQL优化方案:

(01)创建表的时候,分配合适的字段类型和大小;

(02)给经常参与条件检索的单个字段或者多个字段加索引,特例中需要唯一性的,记得加唯一索引。

(03)选择最有效率的表名顺序(笔试常考)
数据库的解析器按照从右到左的顺序处理FROM子句中的表名,
FROM子句中写在最后的表将被最先处理,
在FROM子句中包含多个表的情况下,你必须选择记录条数最少的表放在最后,
如果有3个以上的表连接查询,那就需要选择那个被其他表所引用的表放在最后。
例如:查询员工的编号,姓名,工资,工资等级,部门名
select emp.empno,emp.ename,emp.sal,salgrade.grade,dept.dname
from salgrade,dept,emp
where (emp.deptno = dept.deptno) and (emp.sal between salgrade.losal and

salgrade.hisal)
1)如果三个表是完全无关系的话,将记录和列名最少的表,写在最后,然后依次类推
2)如果三个表是有关系的话,将引用最多的表,放在最后,然后依次类推

(04)WHERE子句中的连接顺序(笔试常考)
数据库采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之左,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的之右。
例如:查询员工的编号,姓名,工资,部门名
select emp.empno,emp.ename,emp.sal,dept.dname
from emp,dept
where (emp.deptno = dept.deptno) and (emp.sal > 1500)

(05)SELECT子句中避免使用*号
数据库在解析的过程中,会将*依次转换成所有的列名,这个工作是通过查询数据字典完成的,这

意味着将耗费更多的时间
select empno,ename from emp;

(06)用TRUNCATE替代DELETE

(07)用WHERE子句替换HAVING子句
WHERE先执行,HAVING后执行

(08)多使用内部函数提高SQL效率

(9)使用表的别名和列的别名

使用表的别名
salgrade s

使用列的别名
ename e

(10)尽可能少使用子查询,可使用left join代替

 


关注公众号,了解更多it技术(it问答网

MySQL锁机制和PHP锁机制

模拟准备–如何模拟高并发访问一个脚本:apache安装文件的bin/ab.exe可以模拟并发量 -c 模拟多少并发量 -n 一共请求多少次 http://请求的脚本
例如:cmd: apache安装路径/bin/ab.exe -c 10 -n 10 http://web.test.com/test.php

【切入正题】
MYSQL中的锁:
语法 :
LOCK TABLE 表名1 READ|WRITE, 表名2 READ|WRITE ……………… 【锁表】
UNLOCK TABLES 【释放表】

Read:读锁|共享锁 : 所有的客户端只能读这个表不能写这个表
Write:写锁|排它锁: 所有当前锁定客户端可以操作这个表,其他客户端只能阻塞
注意:在锁表的过程中只能操作被锁定的表,如果要操作其他表,必须把所有要操作的表都锁定起来!

PHP中的文件锁 (锁的是文件,不是表)
文件锁的文件与表有什么关系?:一点关系也没有,与令牌相似,谁拿到谁操作。所以表根本没锁。
测试时,有个文件就行,叫什么名无所谓。

总结:
项目中应该只使用PHP中的文件锁,尽量避免锁表,因为如果表被锁定了,那么整个网站中所有和这个表相关的功能都被拖慢了(例如:前台很多用户一直下订单,商品表mysql锁表,其他与商品表相关的操作一直处于阻塞状态【读不出来商品表】,因为一个功能把整个网站速度拖慢)。

我的一个项目就是O2O外卖,中午12-2点,晚上6点都是订单高并发时,这种情况下,MySQL锁显然是不考虑的,用户体验太差。其实根据实际的需求,外卖可以不用设计库存量的,当然除了秒杀活动模块还是需要php文件锁的。

应用场景:
1. 高并发下单时,减库存量时要加锁
2. 高并发抢单、抢票时要使用

MySQL锁示例代码:

    <?php  
    /** 
    模拟秒杀活动-- 商品100件 
    CREATE TABLE a 
    ( 
        id int comment '模拟100件活动商品的数量' 
    ); 
    INSERT INTO a VALUES(100); 
    模仿:以10的并发量访问这个脚本!    使用apache自带的ab.exe软件 
     */  
    error_reporting(0);  
    mysql_connect('localhost','root','admin123');  
    mysql_select_db('test');  
      
    # mysql 锁  
    mysql_query('LOCK TABLE a WRITE');// 只有一个客户端可以锁定表,其他客户端阻塞在这  
    $rs = mysql_query('SELECT id FROM a');  
    $id = mysql_result($rs, 0, 0);  
    if($id > 0)  
    {  
        --$id;  
        mysql_query('UPDATE a SET id='.$id);  
    }  
      
    # mysql 解锁  
    mysql_query('UNLOCK TABLES');  

PHP文件锁示例代码:

    <?php  
    /** 
    模拟秒杀活动-- 商品100件 
    CREATE TABLE a 
    ( 
        id int comment '模拟100件活动商品的数量' 
    ); 
    INSERT INTO a VALUES(100); 
    模仿:以10的并发量访问这个脚本!    使用apache自带的ab.exe软件 
     */  
    error_reporting(0);  
    mysql_connect('localhost','root','admin123');  
    mysql_select_db('test');  
    # php中的文件锁  
    $fp = fopen('./a.lock', 'r'); // php的文件锁和表没关系,随便一个文件即可  
    flock($fp, LOCK_EX);// 排他锁  
      
      
    $rs = mysql_query('SELECT id FROM a');  
    $id = mysql_result($rs, 0, 0);  
    if($id > 0)  
    {  
        --$id;  
        mysql_query('UPDATE a SET id='.$id);  
    }  
    # php的文件锁,释放锁  
    flock($fp, LOCK_UN);  
    fclose($fp);  

其实还有一种最简单的方案,一个sql就可以解决这个事情。

@$mysql = mysql_connect('localhost','root','');
mysql_query('set names utf8');
mysql_select_db('test');
mysql_query('UPDATE warehouse SET `stock` = `stock` -1 WHERE `stock` > 0');  //可以避免库存为负数

测试的方法是,找到Apache下的ab.exe,拖入CMD终端,然后输入指定参数测试。

具体参数说明Google一下你就知道,比如耗时之类的…这里不做详细说明。

 

其他参考:

php mysql 锁表和解锁详细语句http://blog.sina.com.cn/s/blog_6e637ea701016r01.html

mysql锁(行锁,表锁)同一用户同一秒操作保持唯一性https://blog.csdn.net/webnoties/article/details/22874431

MySQL锁机制和PHP锁机制 http://phpkim.iteye.com/blog/2294464

Mysql的锁机制与PHP文件锁处理高并发简单思路https://www.cnblogs.com/yuandongdong/p/7560327.html


关注公众号,了解更多it技术(it问答网

mysql表数据发生变化时,主动通知业务系统(mysql-udf-http)

近期接到一个任务,在商家的商品信息发生改变后,要及时通知商家的业务系统,并将变更后的数据同步过去。
第一时间想法是,在主系统的商家编辑模块插入对应代码,当商品编辑后,发送商品id至MQ中,子系统消息订阅,并进行相应处理,感觉不错,但是在主系统进行扩展,系统代码会越来越臃肿。
有没有更好的解决方案,比如让mysql主动通知业务系统,数据发生变化了?于是找到了mysql-udf-http。

mysql-udf-http 是一款简单的MySQL用户自定义函数,具有http_get()、http_post()、http_put()、http_delete()四个函数,可以在MySQL数据库中利用HTTP协议进行REST相关操作,它的安装方式如下:

tar zxvf mysql-udf-http-1.0.tar.gz
cd mysql-udf-http-1.0/
./configure --prefix=/usr/local/mysql --with-mysql=/usr/local/mysql/bin/mysql_config
make && make install

如果提示缺少libcurl,就安装curl

yum install curl*

正常的情况mysql-udf-http.so等文件将安装至/usr/local/mysql/lib/plugin下,不知什么原因我的装在了/usr/local/mysql/lib/mysql/plugin下,于是加个软链

正常的情况mysql-udf-http.so等文件将安装至/usr/local/mysql/lib/plugin下,不知什么原因我的装在了/usr/local/mysql/lib/mysql/plugin下,于是加个软链

安装成功后,进到mysql控制台,注册相关函数

create function http_get returns string soname 'mysql-udf-http.so';
create function http_post returns string soname 'mysql-udf-http.so';
create function http_put returns string soname 'mysql-udf-http.so';
create function http_delete returns string soname 'mysql-udf-http.so'; 

然后在业务表中加入更新操作的触发器

DELIMITER |  
DROP TRIGGER IF EXISTS test_update;  
CREATE TRIGGER test_update  
AFTER UPDATE ON test  
FOR EACH ROW BEGIN  
    SET @tt_re = (SELECT http_get(CONCAT('http://192.168.0.1:8080/my.do?id=', OLD.id)));  
END |  
DELIMITER ;

经测试,当商品表中的数据有更新时,mysql会发送get请求至业务系统。

INSERT 触发器

DELIMITER |  
DROP TRIGGER IF EXISTS test_insert;  
CREATE TRIGGER test_insert  
AFTER INSERT ON test
FOR EACH ROW BEGIN  
    SET @tt_re = (SELECT http_get(CONCAT('http://192.168.0.1:8080/my.do?id=', OLD.id))); 
END |  
DELIMITER ;

DELETE 触发器

DELIMITER |  
DROP TRIGGER IF EXISTS test_delete;  
CREATE TRIGGER test_delete  
AFTER DELETE ON test  
FOR EACH ROW BEGIN  
    SET @tt_re = (SELECT http_get(CONCAT('http://192.168.0.1:8080/my.do?id=', OLD.id)));  
END |  
DELIMITER ; 

下载地址
http://code.google.com/p/mysql-udf-http

csdn下载
http://download.csdn.net/detail/cyantide/9455805

来源:https://blog.csdn.net/cyantide/article/details/50828746

借鉴:https://www.cnblogs.com/phpper/p/7587031.html


关注公众号,了解更多it技术(it问答网

批量更新记录2种方案分析

表结构:
/* 方案一:
foreach($arr as $k=>$v){
$sql=”update obj_config2 set content='”.$v.”‘ where title2='”.$k.”‘”;
mysqli_query($conn,$sql);
}
*/
/*
上面即是循环一条一条的更新记录。一条记录update一次,这样性能很差,也很容易造成阻塞。
那么能不能一条sql语句实现批量更新呢?mysql并没有提供直接的方法来实现批量更新,但是可以用点小技巧来实现。
UPDATE categories
    SET 字段1 = CASE 字段2
        WHEN 1 THEN 3
        WHEN 2 THEN 4
        WHEN 3 THEN 5
    END
WHERE 字段2 IN (1,2,3)
这句sql的意思是,更新 字段1 字段,如果‘字段2‘=1 则‘字段1’ 的值为3,如果‘字段2‘=2 则‘字段1’ 的值为4,如果‘字段2‘=3 则‘字段1’ 的值为5。
*/
//方案二:推荐使用,这个效率更高,因为是拼装成一个完成的sql更新的。
$sql=”update obj_config2 set content = CASE title2  “;
foreach($arr as $k=>$v){
$sql.=”WHEN ‘”.$k.”‘ THEN ‘”.$v.”‘ “;
}
$sql.=”END”;

关注公众号,了解更多it技术(it问答网

mysql时间函数,字符串时间转成时间戳;时间戳转换成字符串

时间函数。
sql:
unix_timestamp($strdate); //把我们的字符串时间-》时间戳格式。

若 $strdate为空!则返回的是当前的时间戳!

FROM_UNIXTIME($intdate);//把我们的时间戳-》字符串。

在sql中如何获得当前的年月日,时分秒?

FROM_UNIXTIME(unix_timestamp());

update users set addtime=FROM_UNIXTIME(unix_timestamp()) where username=’jacky’ and password=’abc123′


关注公众号,了解更多it技术(it问答网