zoukankan      html  css  js  c++  java
  • 彻底理解mysql服务器的字符集转换问题

    主要参考这三个文章:
    https://www.xiariboke.com/article/4147.html
    http://blog.sina.com.cn/s/blog_690c46500100k1nf.html
    http://www.cnblogs.com/springmvc-hibernate/archive/2010/01/04/2484353.html



    1. 字符集以数据库为对象来说, 可以分为数据库内部操作的字符集, (即: character_set_server, database, table,field)和数据库外部的字符集. 1. 其中 character_set_connection是在存储数据库 前的 经过字符集编码转换的 内容. 是 传人字符集. 而character_set_result则是从数据库内部将数据取出来, 发送到客户端时事先经过的编码内容. 是 输出时的字符集. 也就是说, connect的字符集 只是 管 传人的. 不管 输出的 , 而result才是 管输出的.
    1. 注意的是, character_set_client这个字符集, 它只是 向服务器 "声明" 说明的 字符集. 但并不表示 从客户端 (比如Php程序编辑器edit vim notepad等) 传入进来的sql 语句就一定是 (真的是) 这个client, 所以 client具有 欺骗性. 本身没有多大必然的用处.. 但也并不是一定用处都没有 : 当 把传入sql语句 存入 数据库之前, 要把sql语句 从 client指定的字符集 -> 转变为connect字符集. 就起这点作用!
      所以, 最好不要去隐藏和欺骗服务器, 要尽量将 编辑器的字符集和 client的字符集一致

    2. 实际上, 所有的问题, 是 不只是要关注 数据库内部 的存储字符集, 还要关注 从 客户端到 服务器的 连接层 的 字符集: 就是 当 sql语句 连接进来后, 服务器收到 sql语句后, 并不是 马上 就进入 数据库进行存储, 而是要 先 放下来, 经过 connect 连接字符集的处理后, 才能 进入数据库. 这里, connect就相当于 数据库 进门时的 门卫和看守, 而character_set_result就相当于数据库 出库输出 内容的出门 时 的 门卫和看守, 都要 经果他们的 转换的!


    每天自动对 mysql数据库的备份 shell脚本

    1. 备份命令: mysqldump -u root -p db_test > db_name.sql
      还原: 有两种方法, 一是 进入mysql后, 执行 source命令;
      二是, 还是在 shell下, 执行 mysql命令: mysql -u root -p db_name < db_name.sql 跟登录数据库的命令类似, 只是后面 要加上 ( 数据库名称< 脚本名称 )
      推荐 用 第二种 mysql命令, 因为它可以直接在 shell下执行.

    2. 一个常识: 在命令行操作 mysql的命令(相关命令)时, 一定要加上操作用户和密码选项. 这样mysql服务器才能 决定是否有权执行... 而且 指定密码的 方式是: -p 不要直接写密码值.

    mysqladmin 提供了对mysql数据库 从外部的, 状态上的 一个管理, 主要包括这些命令:

    mysqladmin [options] command comand [...]
    最常见的选项是 -uroot -p 通常都要把这两个选项带上

    • create/drop databsename, 只能创建数据库, 不能创建表, 而且不需要用 database这个关键字
    • flush-... 刷新各种权限
    • password 和 old-password 设置密码;
    • 其他辅助命令, ping, processlist. shutdown, status, version, start/stop-slave 从服务器管理.

    1. 学会做人生的减法了.

    2. 现在就是只 管php和mysq语言了, 太多的东西, 已经不能兼顾了.

    3. 要把mysql当作是一个独立的开发语言, 熟悉并能熟练应用 它里面的函数和各种结构的用法.

    4. mysql中的字符串函数包括:
      ascii/char : 将数字和字符进行转换的函数. 比如: ascii('abc') 总是转换第一字符, 配合substr可以 查看任何一个字符, char(89)转换数字到字符
      cast(变量/字段 as to_type): mysql的类型转换函数, 强制转换;
      concat 字符串连接函数: 可以将最终返回字符串 str_ret跟中间 结果的字符串 相连接, 节省一个中间变 量; 可以将数字和数字字符串相连接, 或将数字和字母字符串相连接;
      +: 在mysql中,加号总是用来表示 数字相加, 如果是字符串用加号连接, 总是 尽量 /企图 将"数字字符串" 转换成数字, 所以 如果是字母字符串跟数字相加, 则总是将 字母字符串忽略即为0..

      mysql> select 2a + 3;
      ERROR 1054 (42S22): Unknown column '2a' in 'field list'
      mysql> select '2a' + 3;
      +----------+
      | '2a' + 3 |
      +----------+
      |        5 |
      +----------+
      1 row in set, 1 warning (0.00 sec)
      
      mysql>
      
    字符串截取函数: left(str, length), right(str, length), substring(str, start, length), 
    
    substring_index(str, delimiter, length).
    其中, mid, subst函数 是 substring函数的别名alias.
    需要注意的是, 所有的mysql的字符串截取函数, 首字符start都是从1开始的. 而不是从0开始的.
    
    uuid()函数, 生成36位的随机字符串: 8-4-4-4-12(个数) 的 随机字符串. 分成5个部分: 8, 4,4,4 , 12.
    但是uuid()不适合用来做主键!
    
    replace(str, from, to): replace("abc-amn-axy", 'a", '#'):  结果是: #bc-#mn-#xy.
    instr(haystack, needle): 判断needle在hay中的初始出现的位置,从1开始, 如果没有找到则返回0,hay为 null也返回0.
    
    rand()是生成在0和1之间的 随机数. 可以给rand指定一个参数, 作为种子, 那么 rand(seed)会产生固定的相同的随机数, 改变N种子, 也就能够改变随机数.
    rand() 函数也不需要 进行播种..
    
    要生成 x~ y之间的随机数, 可以使用:  x+(y-x)*rand(); 这个随机数是小数, 还要用 round或floor, ceil来生成整数. 其中 , floor可以得到下限值, 比如x, ceil可以得到 上限值, 比如 y.
    
    
    
    
    
    

    2. 只有 “字符”类型的字段,比如char, varchar, text等才需要指定字符集编码和 collate。其他比如 int, boolean等类型类型则不需要指定 字符集.

    1. 使用$where = " where 1 "; 然后后面的所有条件语句的拼接都可以 and 的统一形式进行书写, 而不 用去判断是否是第一个条件字符串...

    2. 是否可以用 charset 来代替 character set?
      在help create table中, 提示的是 : [default] character set [=] charset_name. 当然你可以用 character set utf8 来指定, 但是 你也可以 [肯定是可以的] 用 charset 来指定. 而且即使你用 character set来指定的字符集, 你用show create table foo;来查看, 显示的结果也是 用的 charset...

      mysql> create table bar(id int not null) character set utf8;
      Query OK, 0 rows affected (0.05 sec)
      
      mysql> show create table bar;
      +-------+--------------------------------------------------------
      ------------+
      | Table | Create Table
                  |
      +-------+--------------------------------------------------------
      ------------+
      | bar   | CREATE TABLE `bar` (
        `id` int(11) NOT NULL
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |            ### 这里的字符集指定都是用的 charset这种简写方式, 和 character set 这种全写方式, 完全是一样的!
      +-------+--------------------------------------------------------
      ------------+
      1 row in set (0.00 sec)
      
      
    3. select 10 where 1; 为什么报错?
      where子句, 只能使用 在 对 "数据表"的 操作中! 也就是里面要有表, 要有字段, 否则就会出错.

    4. 对于where子句来说, 通常是不区分大小写的, 只有在使用 like 条件运算符的时候, 才区分大小写! 如果要区分大小,可以使用 binary关键字, 就是以字节位单位来比较的.

    5. length是按字节来计算的. 而char_length 是按字符个数来计算长度的.

    6. 在mysql中的循环语句, 没有/不支持 for 循环语句! 只有while do end while; repeat util end repeat; lp1: loop ... leave lp1...end loop语句!

    对于mysql而言, 根本就不需要适用 图形化的 客户端界面, 因为那种方式 效率太低, 不能理解/记忆很多的mysql操作语句, 不能深入理解了解mysql的内在, 所以 直接使用 mysql的命令行控制台客户端, 这是每个linux程序员最基本的素质.


    关于select中的rand() 函数的使用??

    • 也就是说, select实际上有两个作用, 有两种使用场景: 一是: 纯粹的输出, print, output, 并不牵涉到 "表的 查询" ! 另一种是: 对表的 操作中, 作为 对表的 查询 动作;
    • **select语句中, 如果牵涉到 表的 查询, 最好是 不要使 用 rand() 函数, 因为使用rand随机函数时, 会进行多次计算和查询. 通常 应该将确定性的 函数如 max, avg , count等放在 select 对 表的 查询语句中, 然后, 将 rand()函数 用在 跟 查询结果的 四则运算中. **
    • 要注意的是, select about_function(rand())语句中, select只是 起到 "输出 "的作用, 并没有 查询的 意思和操作!
      比如: select * from student where id > round(rand()*(select max(id) from student))

    如果要抽出 多个随机性的记录行结果?

    应该使用的方法是: 第一 ,要 能够正确的 适用 rand()函数, 第二, 要在一次查询操作中, 只输出一个 记录行, 然后使用mysql中的循环结构多次输出...
    即:

    while i< rec_num do
         select * from student  where id >  round(rand()*(select max(id) from student)) limit 1;     # id > round(...)的记录有很多个, 我们每次只选择一个limit 1. 
    end while
    

    但是 这个有可能会取到跟上一次 一样的记录, (同一条记录) 因此, 要判断一下, 当前取出的这条记录的某个关键字(key, 或 primary key) 跟上一条记录的primary key是否是一样的, 如果不是一样的 , 则接收, 同时 计数器i 加1, ... 如果是一样的 , 则不接收, 放弃后面的操作, 同时 i也不要 增加.

    set @pre_id=0;
    set @cur_id=0;
    
    while i< rec_num do
         select id into @sel_id , other_filed into @other_field  from user  where id >  round(rand()*(select max(id) from use)) limit 1;    
    
    
        if @pre_id <>  @sel_id then
            set i=i+1;
           -- 返回 @sel_id,  @other_field
    
        end if;
    
        if @pre_id = @cur_id then
        -- 此时 循环变量i 不要加1
        end if;
    
    end while
    
    
    
    

    在mysql中, 可以直接使用 变量, 而不必 事先定义该变量. 但是一个变量, 如果事先没有声明 初始化赋值, 那么 它的值就是 NULL, NULL跟任何东西运算,都将得到NULL.

    MariaDB [test]> select @pre_name;
    +-----------+
    | @pre_name |
    +-----------+
    | NULL      |
    +-----------+
    1 row in set (0.00 sec)
    
    MariaDB [test]> 
    
    

    在 select语句中, 给 变量赋值 有两种方式, 即 select ...into, select a:=b

    select name into @name from t where...
    第二种方法是: select @name2:=name from t where ...
    在这两种方法中, 都不需要 事先 声明/定义/初始化 变量 @name @name2等.
    注意的是, select中 不能 直接使用 a=b 的方式 来 赋值.

    关于mysql中的特殊 常量?

    有三个特殊的常量: TRUE, FALSE, NULL
    这三个特殊常量, 是不分大小写的! 比如: true, True, 都是和TRUE一样的, 同样null和 Null 更 NULL也是一样的! 在写法上没有区别!

    mysql的特殊类型 boolean和 tinyint?

    在mysql中, 是没有boolean 类型的. 而true 和 false 是当做 tinyint(1)来处理的, 注意 这里的1, 表示 的是, 只显示一位数! 并不是说它的取值范围.

    mysql中的游标cursor 的使用? http://www.cnblogs.com/Luouy/p/7301360.html

    mysql中的 循环有三种, while ,和 loop 和 repeat中的 "break 和 continue?"

    1. loop和 repeat中 就相当于 c/c++语言中的 do ....while(condition...)
    2. mysql中, 使用 break和continue的对应 关键字 是: iterate 和 leave
    3. 但是要配合 标号/标识表示: 比如: loop_name: lp:

  • 相关阅读:
    redis
    Ubuntu 用VSFTP搭建FTP服务器
    ADO.NET中高效地使用数据库连接
    类型后面加问号 int?
    system.data.sqlclient.sqlexception:timeout expired
    BackgroundWorker超级详细的用法
    异步调用WCF服务,并将数据填入GridLookUpEdit中
    linq to entity报"不允许启动新事务,因为有其他线程正在该会话中运行."错误解决方法
    sql2005 数据库备份 对于服务器失败
    调用WCF服务返回list集合时出错的解决方法
  • 原文地址:https://www.cnblogs.com/bkylee/p/7826834.html
Copyright © 2011-2022 走看看