specification: 规范, 规格, 产品规范, 产品规格, 技术规范, 产品说明书.
如: create_specification, 等等创建数据库时, 显式地指明, 字符集:
create_specification: 只包括: 字符集和 校验规则的指定: [default] character set [=] charset_name [default] collate [=] collation_namecreate database if not exists db_name [ create_specification]
在mysql中, 很多创建命令 的 create_specification中, 都有很多 [缺省的] keys, 包括: [default,] 等号[=] 是最常见的 缺省项.
即:create schema db_name character set utf8
synonym: 同义词: 创建数据库的另一个 同义词是: create schema
安装好mysql后, 会有四个默认的数据库:
performance_schema , 关于性能检测监视的数据库;
information_schema, 关于数据的数据,叫元数据, 就是关于mysql中有哪些表, 哪些数据库, 哪些权限的数据, 基本上是 视图, 来自基本表, 没有与之相关的 表文件; mysql , 这个是mysql系统的核心, 很多信息都放在mysql中, 包括: user表. db表等等; test; 这个是创建的一个 测试数据库.schema : 框架, (word中 的结构图, 模式, 流程图), 在mysql中, 表示 数据库的意思: 跟 database基本上是一样的.
总结这么多 的 mysql数据库中文乱码的 解决文章, 最终只有两点:
- 不要依赖于 mysql服务器的配置, 因为 在很多实际场合, 你 不能(没有权限)和能力/机会接触到 mysql服务器的配置, 所以 你 根本就不能要求/奢望服务器上的配置 怎么样, 你只能 自己规定/自己 规范/ 显式的 指明 自己创建的数据库的字符集编码;
- 为了 数据库的移植和升级, 你显式地指明了 数据库的编码字符集后, 移植和升级基本上没有 后顾之忧
- 其次, 就是 在每次 连接 字符串/ 连接数据库的时候, 要 显式地指明 你使用的 client/connect(连接层)/result的字符集为 utf8, 即: 显式地写一句:
mysql_query('set names utf8');
但是, 如果你是要在数据库本身上进行操作, 比如创建函数, 创建存储过程, 事件和触发器等, (前提当然是 你能够接触数据库服务器, 而且你还能在上面进程一系列操作), 那么,你最好还是将 关于连接的 相关字符集 都设置成跟数据库的字符集一样的: 比如全部都设置成 utf8. 因为 在存储过程/function 中, 可能牵涉到 某些字符串的 连接/操作函数, 比如 concat 函数, 如果 connection / client/ results(注意是 results复数) 等字符集跟 数据库不一致的时候, 比如在 win系统中, 默认的就是 gbk字符集和 gbk_chinese_ci的collation, 这就跟数据库的utf8不同, 就会报错: illegal operation: mixed different charset... 操作是: set character_set_connection/client/results = utf8;
如果你有机会/有能力 去 设置 mysql的字符集, 你最好在 项目一开始的时候, 就去把 所有的 字符集进行设置, 让他们都一致, 通常推荐 统一的 设置成 utf8.
注意, 在创建/查询等 使用/引用 数据库/表/字段等的时候, 可以不加符号, 如果要加, 就要加 反引号, 而不是 单引号或双引号! 加单引号或双引号会报错!
颠倒, 倒置, invert: grep --invert-match, (-v, 因为-i已经使用为: 忽略大小写)
fedora中, 有一个 yum/dnf包的管理/更新工具: /usr/libexec/packagekitd, 当 dnf在后台 更新 /makecache 的时候, 它会锁定新加入的 dnf命令请求. 可以将 /usr/libexec/packagekitd 服务包卸载, 就能够禁止软件的自动更新.
dnf/yum的使用, 是独占的, 同时只能运行一个dnf进程. 所以如果在后台更新的时候, 你不能使用dnf去下载安装软件的.
gnome的辅助工具有两个: 一个是 tweak-tool, 另一个工具是dconf-editor. 基本上 tweak-tool 微调工具没有多大用途, 主要还是在 dconf-editor中peizhi.
fedora 23 的 软件自动更新, 是通过 gnome-software这个 软件包中心 来 实现的, gnome-software: a software center for gnome. 所以 只要删除 这个 包, 就没有 自动 更新的提示... 当然如果你需要软件自动更新提示的话, 你可以安装 dnf install 'gnome-software' 这个包就行了. 注意的是, fc23中的软件更新提示, 并不是 在 gnome-packagekit-installer包, 所以,不必安装这个..
==============
如何自动实现 mysql的每天 备份?
- 性能方面, mysqldump默认的导出选项已经可以了,单进程的工具不要期望太多
- date命令: date 支持格式化输出: date '+format' , 其中, format包括: %D: %y%m%d, 而时间 就要 全部用大写字母: %H:%M:%S = %T
- 要修改/etc/crontab文件: 共有5个星号, 分为: 分钟 小时 | 日 月 | 星期, 注意没有 年. (年太久远了, 没有什么实际意义!).
- 要重启 crond 服务? crond.service 通常在安装时, 就被系统设置为 开机启动了: 位置在: /etc/systemd/system/ " multi-user.target.wants " / crond.service
- 大致的脚本内容可以自己写:
使用crontab完成mysql的每天备份?
- crontab 中表示时间的字段可以分为 min hour | day month | week. 为了更好的, 更全面的, 更强大的 表示所有完成的任务, 时间的表示方法有多种:
- 可以使用* 通配符, 表示的是每天的每小时和每分钟, 间隔 “每”
- 可以使用逗号, 表示多个时间的列表, 如: 1,2,3,10分钟
- 可以使用横杠, 表示 时间的范围, 比如: 1-10, 20-30
- 可以使用/, 表示“每”的意思, 比如: */10表示每10分钟。
调用的脚本, 应该是linux的脚本 即: *.sh, 可以是linux中的自带命令, 也可以是linux脚本中调用其他存在于
本地机器上的其他程序, 比如php命令, mysql命令。由于 crontab最多是以 “每分钟” 为时间间隔的, 所以如果要实现, 一分钟以内, 每隔多少秒为单位的定时调用, 久需要自己写代码了: 比如:
#! bin/bashstep=2 # 间隔的秒数, 不能大于60for ((i=0; i<60; i+=step)); do$(php '/home/php/crontab/tolog.php')sleep $stepdoneexit 0
然后, 创建crontab, 调用ct.sh每分钟执行一次, 这样实际上就能达到每2秒钟执行一次的要求了。
为了便于移植和升级, 和减少对服务器配置的依赖,在创建数据库的时候,和写php代码的时候, 每次连接sql查询的时候,都明显的, 显式的指定数据库和连接的字符集。
这样,就不用去管 服务器的配置问题了!!
在所有的平台(linux+win等),对于西文字符,你基本上不用考虑字符集的问题, 所谓的乱码, 所谓的字符集的问题, 都只是针对 平台、软件下的 “中文”的存储和显示问题.
基本上, 中文的Windows都是以gbk为系统编码的, 也就是说, win下的软件涉及中文编码字符集问题的时候, 都是以gbk为编码的。
实际上, 虽然latin1 本身可以“存储/表示”gbk或utf8的 字节流, 但是在发生存储 编码转换的时候, 可能就造成了信息的丢失 和 损坏, 甚至有时候, 对输出到 浏览器的编码是正常的, 但是 对于控制台却是乱码的情形, 所以, 为了统一、保险、省心起见, 最好是将 “数据库的内部操作字符集” 和外部的 连接字符集和输出结果字符集 相一致, 推荐的做法是都设置成utf8。
mysql的存储是以字符为单位进行存储的。 不是按字节来存储的, 也就是 对于相同个数的字符, 存储时的字节占用数并不一定相同。 它是按 表示字符串的 “字节流”来进行存储的, 字节流有/占 几个字节,(经过字符集转换后client-> connect -> database. ) 最终 存储时就会花耗几个字节
不管是什么编码, 都是以字符为单位的
即:不管编码如何改变转换, 最终表现出来的 “字符的总的个数 总是不变的”。
- mysql和php的关系? mysql是做sql查询的 , 相当于做菜的厨师,而php相当于 点菜的顾客, 如果你要吃的是非常复杂的满汉全席, 那就要由厨师在后台做好菜后, 才给你端出来 上好菜后, 你在吃。 就相当于php申请查询的mysql的存储过程。 通常是针对比较复杂的处理过程, 才使用存储过程 。但是如果你只是点一盘小菜,青菜的话, 就不需要厨师事先去准备做好后, 再给你端上来, 直接在店里喊一声就可以了,也就是如果是简单的查询请求, 直接使用php的mysql_query('查询字符串'); 就可以了.
mysql的临时表?
使用场合: 凡是需要创建 "会话级" 的表, 即这个表不需要永久存在 , 而只是在 建立会话的时候, 才 "动态"地生成. 而且会话结束, 这个表就自动删除. 然后再次建立会话链接的时候, 这个表又重新动态生成;
所以, 在不同的会话期间, 可以使用 相同的 临时表名称, 相互之间不会影响;临时表也可以创建在内存中, 只要你在最后的时候, create_table_specification中, 指明type=heap就可以了 比如: `create temporary table tmp1 select* from t1 type=heap;临时表的大小 , 受配置文件中的 tmp_table_size的限定
使用临时表最需要注意的是, 临时表中的数据的刷新和清除. 要注意表中的数据的清理 和无效垃圾数据的影响.最好的预防方法 就是要 显式的先删除 drop, 然后再创建, 再插入数据等操作..
在一个会话期, 同一个连接内, 临时表可以连续使用, 所以再次使用前, 应该注意以前的数据清理问题.
尽量避免临时表和 普通表的同名, 因为一旦临时表因为误操作等致使连接断开后, 你操作的就是普通表了. 所以这时候的删除等操作就非常危险, 从而对普通表中的数据产生危险!
很需要注意的一个问题是: 当使用一些 框架的时候, 由于连接是 permanent 持久连接的.所以, 使用临时表的时候, 如果你在多个连接间共享的时候, 临时表中的数据就会重复积累! 要注意这个问题!
临时表和内存表的区别?
- 临时表的存在位置 : 临时表的 结构frame和 数据data, 都是 存在于内存中的!!! 因此, 创建临时表tmp1后, 你在 磁盘上是找不到对应的 表文件的; 相反, 所谓的 内存表
create table mem_table(id int(10) not null ) type=heap ;
它的结构存在于磁盘上的 mem_table.frm中, 只是数据存在于内存中的.. - 临时表的默认存储引擎是myisam 而内存表的默认engine 是memory.
实际中, 应该尽量避免/减少使用临时表??? 参考: http://www.dedecms.com/knowledge/data-base/mysql/2012/0819/7383.html
- 临时表, 分为内存临时表和磁盘临时表, 通常mysql会首先创建使用 内存临时表, 当临时表超过设置值的时候, 会 导出到磁盘临时表;
- 使用临时表意味着 性能低...?
- 尽量避免使用临时表, 优先考虑 对 order by/ group by (排序/分组的) 字段 创建索引.
[临时表相关配置】 tmp_table_size:指定系统创建的内存临时表最大大小; http://dev..com/doc/refman/5.1/en/server-system-variables.html#sysvar_tmp_table_size max_heap_table_size: 指定用户创建的内存表的最大大小; http://dev.mysql.com/doc/refman/5.1/en/server-system-variables.html#sysvar_max_heap_table_size 注意:最终的系统创建的内存临时表大小是取上述两个配置值的最小值。 【表的设计原则】 使用临时表一般都意味着性能比较低,特别是使用磁盘临时表,性能更慢,因此我们在实际应用中应该尽量避免临时表的使用。 如果实在无法避免,也应该尽量避免使用磁盘临时表。 常见的方法有: 1)创建索引:在ORDER BY或者GROUP BY的列上创建索引,这样可以避免使用临时表; 2)分拆很长的列,可以避免使用磁盘临时表:一般情况下,TEXT、BLOB,大于512字节的字符串,基本上都是为了显示信息,而不会用于查询条件,因此表设计的时候,应该将这些列独立到另外一张表。 www.2cto.com 【如何判断使用了临时表】 使用explain查看执行计划,Extra列看到Using temporary就意味着使用了临时表。
为什么要使用视图? 主要还是为了安全:
- 避免误操作, 比如delete, truncate等危险操作.如果在视图上操作的话, 即使误删除了, 真实的基础表中的数据是不会受到影响的.
- 权限开放: 通常基础表中的数据是整个的,全部的, 比如是学校所有专业的学生信息. 然后我创建视图, 每一个专业部/学院, 创建一个视图, 让专业部/学院头头只能看到 和修改 他自己这个部门的学生信息 , 而其他部门的学生信息就无法查看...
另外
- 视图在磁盘上, 没有对应的 数据文件的.只是从其他表中取出来的数据
- 视图相当于一个对 数据的 筛选, 过滤, 它是在使用视图的时候, 才动态生成的...
- 视图中的数据 可以来源于:基础表, 和其他视图.
- 视图相当于窗口,提供多角度的 对数据的查看形式.
所以 视图的使用, 就相当于普通表, 在很多重要应用上, 用户操作的, 和所看到的, 其实很多都是视图, 而不是基础表.还是很重要很必要的.
要生成表中的数据, 不必到处去找, 导入, 直接在mysql中,写一个存储过程, 来自动批量地插入数据. 批量插入"测试数据的存储过程" 如下: 参考" https://segmentfault.com/q/1010000000137096
- 要修改存储过程, 格式是 alter procedure sp_name [characteristic] characteristic: adj: 独有的, 独特的; n. 特征, 特性. 复数是: characteristics 注意这个语句, 不能直接修改 存储过程的 参数和过程体, 要修改参数和过程的实体内容, 你要先将sp, drop掉, 然后再重新创建, recreate.
1. 产生一个随机小写字母的函数: 首先要在全局// 设置 [mysqld] 中 定义 log-bin-trust-function-creators=11. 函数体: (产生随机大写字母的函数, ruc()就只是把 cs的默认值设置为 26个大写字母 ) create definer='root'@'localhost' function rlc() returns char(1) begin declare cs char(26) default 'abcdefghijklmnopqrstuvwxyz'; return substr(cs, floor(1+26*rand()), 1); end//-- 随机产生1个大写字母 create function ruc() returns char(1) begin declare cs char(26) default 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; return substr(cs, floor(1+26*rand()), 1); end//-- 生成随机英文名字,并插入到表中drop procedure if exists sp_genRandEnName;delimiter //create definer='root'@'localhost' procedure sp_genRandEnName(in persons int unsigned)comment 'this is random test data generator'begin declare i int unsigned default 0; declare j int unsigned default 0; declare ename char(20) default ''; declare nl tinyint default 0; -- 英文名字的随机长度值 , 这个地方看句首的 decalre就要出错了: 会报错:ERROR1064(42000) while inl end repeat; -- 插入到数据表中 insert into `user`(id, name) values('', ename); set i=i+1; end while;end//delimiter ;-------------最后 实测可用的 , 通过测试后的 代码是:truncate user;drop procedure if exists sp_genRandEnName;delimiter //create definer='root'@'localhost' procedure sp_genRandEnName(in persons int unsigned)begin declare i int unsigned default 0; declare j int unsigned default 0; declare ename char(20) default ''; -- 这里规定 ename的最大长度, 比如为10 declare nl tinyint default 0; while i nl end repeat; insert into `user`(id, name) values('', ename); set i=i+1; end while;end//delimiter ;
// 生成随机中文名字的 姓和名: http://blog.csdn.net/gjq246/article/details/72771939-- 生成姓氏和名字的 辅助函数rxing(), rming();CREATE DEFINER=`root`@`localhost` FUNCTION `rxing`() RETURNS char(1) CHARSET utf8begin declare cs char(10) default '赵钱孙李周吴郑王冯陈诸卫蒋沈韩杨朱秦尤许何吕施张孔曹严华金魏陶姜戚谢邹喻柏水窦章云苏潘葛奚范彭郎鲁韦昌马苗凤花方俞任袁柳酆鲍史唐费廉岑薛雷贺倪汤滕殷罗毕郝邬安常乐于时傅皮齐康伍余元卜顾孟平黄和穆萧尹姚邵堪汪祁毛禹狄米贝明臧计伏成戴谈宋茅庞熊纪舒屈项祝董粱杜阮蓝闵席季麻强贾路娄危江童颜郭梅盛林刁钟徐邱骆高夏蔡田樊胡凌霍虞万支柯咎管卢莫经房裘干解应宗丁宣贲邓郁单杭洪包诸左石崔吉钮龚'; -- 常用的姓氏汉字, 共190个 return substr(cs, floor(1+190*rand()), 1); endCREATE DEFINER=`root`@`localhost` FUNCTION `rming`() RETURNS char(1) CHARSET utf8begin declare cs varchar(500) default '明国华建文平志伟东海强晓生光林小民永杰军金健一忠洪江福祥中正振勇耀春大宁亮宇兴宝少剑云学仁涛瑞飞鹏安亚泽世汉达卫利胜敏群波成荣新峰刚家龙德庆斌辉良玉俊立浩天宏子松克清长嘉红山贤阳乐锋智青跃元武广思雄锦威启昌铭维义宗英凯鸿森超坚旭政传康继翔栋仲权奇礼楠炜友年震鑫雷兵万星骏伦绍麟雨行才希彦兆贵源有景升惠臣慧开章润高佳虎根远力进泉茂毅富博霖顺信凡豪树和恩向道川彬柏磊敬书鸣芳培全炳基冠晖京欣廷哲保秋君劲轩帆若连勋祖锡吉崇钧田石奕发洲彪钢运伯满庭申湘皓承梓雪孟其潮冰怀鲁裕翰征谦航士尧标洁城寿枫革纯风化逸腾岳银鹤琳显焕来心凤睿勤延凌昊西羽百捷定琦圣佩麒虹如靖日咏会久昕黎桂玮燕可越彤雁孝宪萌颖艺夏桐月瑜沛诚夫声冬奎扬双坤镇楚水铁喜之迪泰方同滨邦先聪朝善非恒晋汝丹为晨乃秀岩辰洋然厚灿卓杨钰兰怡灵淇美琪亦晶舒菁真涵爽雅爱依静棋宜男蔚芝菲露娜珊雯淑曼萍珠诗璇琴素梅玲蕾艳紫珍丽仪梦倩伊茜妍碧芬儿岚婷菊妮媛莲娟一'; -- 常用 的名字中的 名 汉字. 共400个 return substr(cs, floor(1+400*rand()), 1); end -- 生成随机2~3个汉字的中文名字的存储过程CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_genRandChName`(in persons int unsigned)begin declare i int unsigned default 0; declare j int unsigned default 0; declare cname char(3) default ''; declare nl tinyint default 0; while inl end repeat; insert into `user`(id, name) values('', cname); set i=i+1; end while;end
当在控制台,用
update user set password=password('root') where user='root' and 'host'='localhost';
修改了用户, 比如root的配置文件后 , 一定 要用flush privileges;
来 刷新授权, 这时新设置的密码 才能生效. 否则, 如不刷新权限,即使你设置了新密码, 再次登录时,仍然会认为没有密码, 或是之前的密码, 这样的话, 就会报错! 这是实践 经历过的.通过help 可知, 修改数据库的时候,语法格式是:
alter {database | schema } db_name alter_specification
注意, 这里常见的通用方法是: 如果是create, 则是: create _key_ _name_ create_specification
如果是 alter的话,则是: alter _key_ _name_ alter_specification.
mysql> alter database test character set utf8;Query OK, 1 row affected (0.00 sec)mysql> show create database test;+----------+---------------------------------------------------------------+| Database | Create Database |+----------+---------------------------------------------------------------+| test | CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET utf8 */ |+----------+---------------------------------------------------------------+1 row in set (0.00 sec)mysql>
要注意, 修改字符集的步骤和操作, 应该放在 创建表 等任何操作之前! 否则,原来数据库/表中 的数据 就会出错乱码!
1.rescure笔记本
如何强制修改foo简单密码 假装忘记密码? 同时开启两个字符终端?linux桌面版确实不如windows稳定, 但服务器就不是一个水平了
linux稳定说的是内核稳定, 不是说图形界面稳定, 应该极少出现像windows那样彻底死机那样的问题, gui挂掉,貌似内核还可以正常运行? linux的优势不再桌面 linux系统和图形界面没有必然的联系 linux内核和图形界面是通过接口连接的, 不是内核的一部分。 而windows的图形界面是内核的一部分, 所以图形界面的稳定性不如windows。 但是同时也正因如此, windos内核的稳定性受到gui的影响不如linux稳定。强行关机后, fedora就不能启动了, 根本原因是: 分区表的逻辑错误? 使用PQ就是定时炸弹?
强行关机后 当check到根路径的时候, 就check到错误而无法继续下去了??
要查看linux的启动信息, 启动时一闪而过, 可以在 启动后, 通过命令dmesg来查看: dmesg: dump message.
如何把man和info的信息存储为文本文件? 如: man tcsh | col -b > tcsh.txt info tcsh -o tcsh.txt -s
linux如何强行退出x: 有时候, 因为程序错误, 使鼠标和键盘都无法响应和反应时, 可以强制退出图形界面,按ctrl+alt+backspace(不是shift)
9. 要设置 禁用: linux的快捷键为disabled, 不要按delete键(delete键是一个 合法的/有用的键), 要按backspace.
gzip 的压缩和 解压缩使用方法?
- Usage: zip [OPTION]... [FILE]... 格式用法: 通常来说, 冒号,引号,分号等标点符号要紧跟前面的单词, 后面要隔一个空格, 像省略号也要紧跟前面的单词, 当做是一个单词整体比如: [file]... 英语中的省略号是 3个圆点,而不是中文的6个
- 压缩是gzip, 解压是: gzip -d 或 gunzip. 其中的-d表示 --decompress. 或 uncompress
- 压缩本身考虑了 压缩的时间, 和 压缩后文件的大小 之间的平衡关系, 当然你可以自己指定 压缩的大小(better) 或 压缩的快慢(faster). 数字选项从-1, 到-9...
- 压缩时, 会直接将原文件改名, 即源文件不保留, 当然 可以用 -k --keep 保留原来的文件.
- 解压时, 可以不指定后面 的 .gz, 比如: 直接适用 gzip -d foo 就表示 解压 foo.gz这个压缩包.
- 如果不指定 输入文件, 则是 对stdin 进行 压缩, 这个在 很多 管道 操作 中很有用!
- 使用, -r --recursive 选项, 可以对 目录进行递归压缩. 注意这时候, 不是对目录本身进行压缩, 而是对目录中 的文件 进行一个一个的 压缩.
在mysql中, 任何一个操作(包括, insert等dml, alter等 ddl, 都可以看做是一个事务, transaction(用名词形式); 有可以用 commit或rollback来处理.
- 可以在命令行 shell中, 执行任意sql内容的脚本, 包括导出数据库 包括插入数据, 包括定义和执行存储过程等的 sql文件. 也就是, 执行 的内容不只是 限于 数据库的导出和导入等
- 方式是: 执行mysql -uroot -p [password] < my.sql 注意这个password, 很多时候, 是不能直接给出来的, 但是在这里这个shell界面, 它是可以直接给出的. the password to use when connecting to server. If password is not given it's asked from tty
- 可以在mysql命令中, 直接用 -D 或 --database=.... 来指明所用的数据库, 当然最好的方法是 直接在sql文件中, 指定要使用的数据库...
关于delimiter的改变, 并不是 在定义/创建 所有的 sql语句, sql文件时, 都需要 使用 delimiter的! 即使是在同一个 脚本文件中, 也只有在定义 创建 包含begin...end 里面有多条语句的 procedure和function 过程和函数的时候, 才需要, 在procedure和function前后的 其他单条单条的语句, 只要不涉及 procedure和function的语句 还是 用分号. 而且 存储过程和函数 两端 首尾的 delimiter语句应该对应成对使用...
处理 mysql异常的语句和 写法?
- 基本处理流程是: 先声明异常处理方式, 然后再写事务, 最后 根据 _err 值来 决定 提交还是 回滚...
- 异常处理方式有两种, 一是continue 一是 exit
- 异常的 情况有很多, 在for子句中声明, 声明的时候, 可以用 笼统的'全部"的声明,如: sqlexception, 也可以用具体的 某一条异常的名称或代号来表示: 如: for not found , for sqlstate '0200' , 或直接用 mysql的内部错误号 for 1200 等
- 异常的处理方式有 设置某个标识变量的值, 或直接输出 提示语句 set _err=1 , 或 : select 'not found...'
1 use test; 2 select * from `user`; select round(rand()*1000) as '随机数'; 3 delimiter // 4 -- create definer='root'@'localhost' procedure gentd(in count int) 5 -- begin 6 -- select round(rand()*1000) as '随机数'; 7 /* mysql 不支持 # 注释? */ 8 drop procedure if exists foo// 9 create procedure foo() 10 begin 11 declare _err integer default 0; 12 declare continue handler for sqlexception set _err=1; 13 14 16 start transaction; -- 这是一条语句! start transaction 后面要加上 分号! 17 insert foo(id, name) values('', 'foo'); 18 insert foo(id, name) values('', 'bar'); 21 22 if _err=1 then 23 select 'ERROR! 回滚操作...'; 24 rollback; 25 else 26 commit; 27 end if; 28 29 select _err as 'status'; 30 31 end// 32 delimiter ; 33 34 call foo(); -- 这句话很重要@ 存储过程 就跟函数一样, 你光是 定义它, 创建它没用, 如果你不执行它, 他是不会自动 执行的! 所以要显式的 调用 去执行它!!
适用 vim的好处: 格式化代码的命令, 是 等号 = , 取其 两端 对齐 的 意思, == 格式化当前行, gg=G 格式化整个代码, #= 比如: 4= 格式化当前行后面的4行.
mysql中, declare语句必须放在 function函数或 存储过程中, 不能直接在 mysql控制台使用.
关于 在不同的 mysql版本中, 版本4.1 和 版本 5.0对 varchar的 规定的 变化: 参考 : http://www.cnblogs.com/doit8791/archive/2012/05/28/2522556.html
- 4.1版本以下, varchar的字节长度是 255, 而5.0以上版本的varchar的字节长度最大是 65535字节, 即 64KB.
- 同样的 varchar(20) 的含义不同, 4.1版本以前, 表示的是 varchar 20个字节, 如果存储utf8汉子, 则只能存放6个汉字, 而对于5.0以上的版本 varchar(20)则表示最多可以存储 20个 字符! 注意是字符, 不再是字节了.
- 因此, 在5.0以上版本, varchar最多 可以存放: 65535/3 = 21845 个汉字, 实际使用时, 可以规定常见的 varchar(1000), varchar(1024), varchar(2000);
杂项: 1. commit和 comment的区别, 都是mm 只是后面的两个字母不同, 一个是i, 一个是 en; 查看数据库中 有哪些函数和 存储过程, 适用的命令 不是 show functions, show procedures, 而是 show function status, 和 show procedure status
注意 , 函数和 procedure都不要 带 复数s!
mysql 创建函数时经常遇到的问题? 参考: http://mamicode.com/info-detail-1841394.html
- 通常不要去指定什么 definer~ 因为默认的就是 'root'@'localhost', 没有什么问题, 而且定义definer也没用什么意义! 最重要的是, 容易出错, 容易把 'definer'写出'define' 而很难排错!
- 存储过程中, 可以使用 'if not exists', 但是在函数中 就不能使用 if not exists!
- 在存储过程中, 的参数,不能使用 带@的, 而且不能设置默认值, 如果是字符串类型,必须指定长度
- 调用存储过程时, 必须使用用户变量带 @的, 不能使用没有@的变量, 因为那是局部变量, 局部变量和 函数调用中的 不带@ 的变量不能区分. 这个自不必然说, 你如果直接输入不带@的变量, 会提示没有那样的 "field" 错误.
调用函数的时候, 参数个数要 正确, 即使你不用 这个参数的值, 你也要输入null 来占位.
一个mysql语句, 可以是简单的 insert/select语句, 也可以是 begin...end 的复合语句, 复合语句中, 可以包含 变量声明, 和其他条件/选择/循环结构语句等.
1) function与procedure的区别:一个有返回值,一个没有,仅此而已。上述说法是错误的,function和procedure的用法有很多不同,总体来说procedure受到的限制较少,function的限制较多;而且procedure可以使用out参数返回值,因此尽量采用procedure