背景:在MySQL与PostgreSQL的对比中,PG的JSON格式支持优势总是不断被拿来比较。最主要是json这种东西在做一些物联网时用php结合很有用处。
========================真实实践成功如下所示AddTime:2016-12-4==================================
CREATE TABLE json_test(  
id INT,  
person_desc TEXT  
)ENGINE INNODB;  

INSERT INTO json_test VALUES (1,'
    {  
    "programmers": [{  
        "firstName": "Brett",  
        "lastName": "McLaughlin",  
        "email": "aaaa"  
    }, {  
        "firstName": "Jason",  
        "lastName": "Hunter",  
        "email": "bbbb"  
    }, {  
        "firstName": "Elliotte",  
        "lastName": "Harold",  
        "email": "cccc"  
    }],  
    "authors": [{  
        "firstName": "Isaac",  
        "lastName": "Asimov",  
        "genre": "sciencefiction"  
    }, {  
        "firstName": "Tad",  
        "lastName": "Williams",  
        "genre": "fantasy"  
    }, {  
        "firstName": "Frank",  
        "lastName": "Peretti",  
        "genre": "christianfiction"  
    }],  
    "musicians": [{  
        "firstName": "Eric",  
        "lastName": "Clapton",  
        "instrument": "guitar"  
    }, {  
        "firstName": "Sergei",  
        "lastName": "Rachmaninoff",  
        "instrument": "piano"  
    }]  
}');  

ALTER TABLE json_test MODIFY person_desc json;  



{
    "programmers":[
        {
            "firstName":"Brett",
            "lastName":"McLaughlin",
            "email":"aaaa"
        },
        {
            "firstName":"Jason",
            "lastName":"Hunter",
            "email":"bbbb"
        },
        {
            "firstName":"Elliotte",
            "lastName":"Harold",
            "email":"cccc"
        }
    ],
    "authors":[
        {
            "firstName":"Isaac",
            "lastName":"Asimov",
            "genre":"sciencefiction"
        },
        {
            "firstName":"Tad",
            "lastName":"Williams",
            "genre":"fantasy"
        },
        {
            "firstName":"Frank",
            "lastName":"Peretti",
            "genre":"christianfiction"
        }
    ],
    "musicians":[
        {
            "firstName":"Eric",
            "lastName":"Clapton",
            "instrument":"guitar"
        },
        {
            "firstName":"Sergei",
            "lastName":"Rachmaninoff",
            "instrument":"piano"
        }
    ]
}





mysql> SELECT id,json_keys(person_desc) as "keys" FROM json_test\G
*************************** 1. row ***************************
  id: 1
keys: ["authors", "musicians", "programmers"]
1 row in set (0.00 sec)


mysql>  SELECT json_extract(AUTHORS,'$.lastName[0]') AS 'name', AUTHORS FROM  
    ->     (  
    ->     SELECT id,json_extract(person_desc,'$.authors[0][0]') AS "authors" FROM json_test  
    ->     UNION ALL  
    ->     SELECT id,json_extract(person_desc,'$.authors[1][0]') AS "authors" FROM json_test  
    ->     UNION ALL  
    ->     SELECT id,json_extract(person_desc,'$.authors[2][0]') AS "authors" FROM json_test  
    ->     ) AS T1  
    ->     ORDER BY NAME DESC;
+------------+----------------------------------------------------------------------------+
| name       | AUTHORS                                                                    |
+------------+----------------------------------------------------------------------------+
| "Williams" | {"genre": "fantasy", "lastName": "Williams", "firstName": "Tad"}           |
| "Peretti"  | {"genre": "christianfiction", "lastName": "Peretti", "firstName": "Frank"} |
| "Asimov"   | {"genre": "sciencefiction", "lastName": "Asimov", "firstName": "Isaac"}    |
+------------+----------------------------------------------------------------------------+
3 rows in set (0.00 sec)



mysql> SELECT  
    -> json_extract(AUTHORS,'$.firstName[0]') AS "firstname",  
    -> json_extract(AUTHORS,'$.lastName[0]') AS "lastname",  
    -> json_extract(AUTHORS,'$.genre[0]') AS "genre"  
    -> FROM  
    -> (  
    -> SELECT id,json_extract(person_desc,'$.authors[0]') AS "authors" FROM json_test  
    -> ) AS T\G ;
*************************** 1. row ***************************
firstname: "Isaac"
lastname: "Asimov"
    genre: "sciencefiction"
1 row in set (0.00 sec)

修改的方法,注意加双引号:
mysql> update json_test set  person_desc=json_set(person_desc,"$.authors[2].firstName",'dong');
Query OK, 1 row affected (0.04 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT id,json_extract(person_desc,'$.authors[2].firstName') AS "authors" FROM json_test;
+------+---------+
| id   | authors |
+------+---------+
|    1 | "dong"  |
+------+---------+
1 row in set (0.00 sec)



自己设计一个Json串的字段:
  {  
    "deviceinfo": [{  
        "chineseName": "蛋壳孵化I型",  
        "EnglishName": "LevooAllCanBeHatch",  
        "deviceMacAdd": "00-50-56-C0-00-08"  
    }],  
    "tcpserverinfo": [{  
        "fd": "Isaac",  
        "connTime": "2014-11-11 23:45:21",  
        "connIp": "127.0.0.1"  
    }],  
    "websocketinfo": [{  
        "fd": "1",  
        "connTime": "2014-11-11 23:45:21",  
        "connIp": "127.0.0.1"  
    }, {  
        "fd": "21",  
        "connTime": "2014-11-11 23:45:21",  
        "connIp": "127.0.0.2"  
    }]  
}


mysql> update `json_test` set person_desc=json_set(person_desc, "$.deviceinfo[0].chineseName", '蛋壳108') where id=20;          
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0


mysql>  SELECT * FROM json_test where id=20\G;
*************************** 1. row ***************************
         id: 20
person_desc: {"deviceinfo": [{"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108", "deviceMacAdd": "00-50-56-C0-00-08"}], "tcpserverinfo": [{"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}], "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)




Json的格式更简单一些:
  {  
    "deviceinfo": {  
        "chineseName": "蛋壳孵化I型",  
        "EnglishName": "LevooAllCanBeHatch",  
        "deviceMacAdd": "00-50-56-C0-00-08"  
    },  
    "tcpserverinfo": {  
        "fd": "Isaac",  
        "connTime": "2014-11-11 23:45:21",  
        "connIp": "127.0.0.1"  
    },  
    "websocketinfo": [{  
        "fd": "1",  
        "connTime": "2014-11-11 23:45:21",  
        "connIp": "127.0.0.1"  
    }, {  
        "fd": "21",  
        "connTime": "2014-11-11 23:45:21",  
        "connIp": "127.0.0.2"  
    }]  
}
mysql> update `json_test` set person_desc=json_set(person_desc, "$.deviceinf.chineseName", '蛋壳108') where id=30;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1  Changed: 0  Warnings: 0


=================================================================================================================
mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳孵化I型", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)

mysql> update `json_test` set person_desc=json_set(person_desc, "$.deviceinfo.chineseName", '蛋壳1081') where id=30;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳1081", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)


=================================================================================================================
mysql> update `json_test` set person_desc=json_set(person_desc, "$.deviceinfo.chineseName", '蛋壳108109') where id=30;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108109", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)

===================================================================================================================
mysql> update `json_test` set person_desc=json_set(person_desc, "$.tcpserverinfo.fd", '蛋壳108109') where id=30;                      
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0



======================================================修改二级=====================================================
mysql> update `json_test` set person_desc=json_set(person_desc, "$.websocketinfo[1].fd", '22') where id=30;                                
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108109", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "蛋壳108109", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "22", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)


=================================插入新的数组属性===================================
mysql> update `json_test` set person_desc=json_insert(person_desc, "$.websocketinfo[1].fdfd", '2222') where id=30;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108109", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "蛋壳108109", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "22", "fdfd": "2222", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}


最后想了一下,那个websocket是没有啥用的,直接简单化即可:
{
    "deviceinfo":{
        "EnglishName":"LevooAllCanBeHatch",
        "chineseName":"蛋壳108109",
        "deviceMacAdd":"00-50-56-C0-00-08"
    },
    "tcpserverinfo":{
        "fd":"蛋壳108109",
        "connIp":"127.0.0.1",
        "connTime":"2014-11-11 23:45:21"
    },
    "websocketinfo":[
        {
            "fd":"1",
            "connIp":"127.0.0.1",
            "connTime":"2014-11-11 23:45:21"
        }
    ]
}



josn类不能有如下默认值:
{
    "deviceinfo":{
        "EnglishName":"N/A",
        "chineseName":"N/A",
        "deviceMacAdd":"N/A"
    },
    "tcpserverinfo":{
        "fd":"N/A",
        "connIp":"N/A",
        "connTime":"N/A"
    },
    "websocketinfo":[
        {
            "fd":"N/A",
            "connIp":"N/A",
            "connTime":"N/A"
        }
    ]
}



php json.php
{
    "deviceinfo":{
        "EnglishName":"N/A",
        "chineseName":"N/A",
        "deviceMacAdd":"N/A"
    },
    "tcpserverinfo":{
        "fd":"N/A",
        "connIp":"N/A",
        "connTime":"N/A"
    },
    "websocketinfo":[
        {
            "fd":"N/A",
            "connIp":"N/A",
            "connTime":"N/A"
        }
    ]
}Array
(
    [deviceinfo] => Array
        (
            [EnglishName] => N/A
            [chineseName] => N/A
            [deviceMacAdd] => N/A
        )

    [tcpserverinfo] => Array
        (
            [fd] => N/A
            [connIp] => N/A
            [connTime] => N/A
        )

    [websocketinfo] => Array
        (
            [0] => Array
                (
                    [fd] => N/A
                    [connIp] => N/A
                    [connTime] => N/A
                )

        )

)



mysql> select json_extract(data,'$.tcpserverinfo.fd') as fd from hatch_dev_temp where hatchdevid=1;
+----------------+
| fd             |
+----------------+
| "蛋壳108109"   |
+----------------+
1 row in set (0.00 sec)


=============================================================================================
mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳孵化I型", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)

mysql> update `json_test` set person_desc=json_set(person_desc, "$.deviceinfo.chineseName", '蛋壳1081') where id=30;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳1081", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)


=============================================================================================
mysql> update `json_test` set person_desc=json_set(person_desc, "$.deviceinfo.chineseName", '蛋壳108109') where id=30;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108109", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "Isaac", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "21", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)

===================================================================================================================
mysql> update `json_test` set person_desc=json_set(person_desc, "$.tcpserverinfo.fd", '蛋壳108109') where id=30;                      
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0



======================================================修改二级=====================================================
mysql> update `json_test` set person_desc=json_set(person_desc, "$.websocketinfo[1].fd", '22') where id=30;                                
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108109", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "蛋壳108109", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "22", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}
1 row in set (0.00 sec)


=================================插入新的数组属性===================================
mysql> update `json_test` set person_desc=json_insert(person_desc, "$.websocketinfo[1].fdfd", '2222') where id=30;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM json_test where id=30\G;
*************************** 1. row ***************************
         id: 30
person_desc: {"deviceinfo": {"EnglishName": "LevooAllCanBeHatch", "chineseName": "蛋壳108109", "deviceMacAdd": "00-50-56-C0-00-08"}, "tcpserverinfo": {"fd": "蛋壳108109", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, "websocketinfo": [{"fd": "1", "connIp": "127.0.0.1", "connTime": "2014-11-11 23:45:21"}, {"fd": "22", "fdfd": "2222", "connIp": "127.0.0.2", "connTime": "2014-11-11 23:45:21"}]}


最后想了一下,那个websocket是没有啥用的,直接简单化即可:
{
    "deviceinfo":{
        "EnglishName":"LevooAllCanBeHatch",
        "chineseName":"蛋壳108109",
        "deviceMacAdd":"00-50-56-C0-00-08"
    },
    "tcpserverinfo":{
        "fd":"蛋壳108109",
        "connIp":"127.0.0.1",
        "connTime":"2014-11-11 23:45:21"
    },
    "websocketinfo":[
        {
            "fd":"1",
            "connIp":"127.0.0.1",
            "connTime":"2014-11-11 23:45:21"
        }
    ]
}



josn类不能有如下默认值:
{
    "deviceinfo":{
        "EnglishName":"N/A",
        "chineseName":"N/A",
        "deviceMacAdd":"N/A"
    },
    "tcpserverinfo":{
        "fd":"N/A",
        "connIp":"N/A",
        "connTime":"N/A"
    },
    "websocketinfo":[
        {
            "fd":"N/A",
            "connIp":"N/A",
            "connTime":"N/A"
        }
    ]
}

修改tcpserver里的fd的句柄及查询该句柄的值:
mysql> update hatch_dev_temp set data=json_set(data, "$.tcpserverinfo.fd", '108') where hatchdevid=1;                                
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select json_extract(data,'$.tcpserverinfo.fd') as fd from hatch_dev_temp where hatchdevid=1;    
+-------+
| fd    |
+-------+
| "108" |
+-------+
1 row in set (0.00 sec)

mysql> update hatch_dev_temp set data=json_set(data,"$.tcpserverinfo.fd",22) where hatchdevid=1;    
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql>  select json_extract(data,'$.tcpserverinfo.fd') as fd from hatch_dev_temp where hatchdevid=1;  
+------+
| fd   |
+------+
| 22   |
+------+
1 row in set (0.00 sec)


EOF
========================================================================================


修改json数据:
JSON_SET(json_doc, path, val[, path, val] ...)
修改数据

update t set js=json_set('{"a":1,"s":"abc"}','$.a',456,'$.b','bbb') where id=1

结果js={"a":456,"s":"abc","b":"bbb"}

path中$就代表整个doc,然后可以用javascript的方式指定对象属性或者数组下标等.
执行效果,类似json的语法
$.a=456
$.b="bbb"

存在就修改,不存在就设置.

$.c.c=123
这个在javascript中会出错,因为.c为null。
但是在json_set('{}','$.c.c',123)中,不存在的路径将直接被忽略。
来自:http://blog.5ibc.net/p/36344.html
http://jackyrong.iteye.com/blog/2282003
多唯json数组的修改处理方法:
http://blog.csdn.net/yueliangdao0608/article/details/49760213


MySQL 5.7.7 labs版本开始InnoDB存储引擎已经原生支持JSON格式,该格式不是简单的BLOB类似的替换。原生的JSON格式支持有以下的优势:
JSON数据有效性检查:BLOB类型无法在数据库层做这样的约束性检查
查询性能的提升:查询不需要遍历所有字符串才能找到数据
支持索引:通过虚拟列的功能可以对JSON中的部分数据进行索引


来自:http://database.51cto.com/art/201504/472302.htm


-------------------------------------------------------------------------------------------------------------------------
MySQL 5.7原生JSON格式支持:


可以看到我们新建了表user,并且将列data定义为了JSON类型。这意味着我们可以对插入的数据做JSON格式检查,确保其符合JSON格式的约束,如插入一条不合法的JSON数据会报如下错误:
mysql> insert into user values (NULL,"test");
ERROR 3130 (22032): Invalid JSON text: "Invalid value" at position 2 in value (or column) 'test'.
此外,正如前面所说的,MySQL 5.7提供了一系列函数来高效地处理JSON字符,而不是需要遍历所有字符来查找,这不得不说是对MariaDB dynamic column的巨大改进:

当然,最令人的激动的功能应该是MySQL 5.7的虚拟列功能,通过传统的B+树索引即可实现对JSON格式部分属性的快速查询。使用方法是首先创建该虚拟列,然后在该虚拟列上创建索引:

然后可以通过添加的索引对用户名进行快速的查询,这和普通类型的列查询一样。而通过explain可以验证优化器已经选择了在虚拟列上创建的新索引:
mysql> explain select * from user where user_name='"Amy"'\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: user
   partitions: NULL
         type: ref
possible_keys: idx_username
          key: idx_username
      key_len: 131
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)
可以发现MySQL 5.7对于JSON格式堪称完美

摘自:http://www.innomysql.net/article/15319.html



修改json地址:
mysql> set @json='["apple", {"attr": [50, true], "name": "orange"}]';
Query OK, 0 rows affected (0.00 sec)

mysql> select json_insert(@json, '$[1].attr[0]', 2, '$[2]', "pear");
+-----------------------------------------------------------+
| json_insert(@json, '$[1].attr[0]', 2, '$[2]', "pear")     |
+-----------------------------------------------------------+
| ["apple", {"attr": [50, true], "name": "orange"}, "pear"] |
+-----------------------------------------------------------+
1 row in set (0.00 sec)

mysql> select json_replace(@json, '$[1].attr[0]', 2, '$[2]', "pear");
+--------------------------------------------------------+
| json_replace(@json, '$[1].attr[0]', 2, '$[2]', "pear") |
+--------------------------------------------------------+
| ["apple", {"attr": [2, true], "name": "orange"}]       |
+--------------------------------------------------------+
1 row in set (0.00 sec)

mysql>  select json_set(@json, '$[1].attr[0]', 2, '$[2]', "pear");
+----------------------------------------------------------+
| json_set(@json, '$[1].attr[0]', 2, '$[2]', "pear")       |
+----------------------------------------------------------+
| ["apple", {"attr": [2, true], "name": "orange"}, "pear"] |
+----------------------------------------------------------+
1 row in set (0.01 sec)

mysql> select json_remove(@json, '$[1].attr[0]', '$[2]');
+-----------------------------------------------+
| json_remove(@json, '$[1].attr[0]', '$[2]')    |
+-----------------------------------------------+
| ["apple", {"attr": [true], "name": "orange"}] |
+-----------------------------------------------+
1 row in set (0.00 sec)
在phpMyAdmin中提示“Configuration of pmadb… not OK”,如下图所示:
“Configuration of pmadb… not OK”解决办法,这个问题不大,不影响使用,仅仅是一个警告。如果不想总是看见这个警告,可以用如下办法来解决。

(1)初始化phpmyadmin数据库
cd /Library/WebServer/Documents/phpmyadmin/sql
mysql -u root -p < create_tables.sql
Enter password:

mysql> CREATE DATABASE phpmyadmin;
Query OK, 1 row affected (0.02 sec)

mysql> use phpmyadmin
Database changed
mysql> source /data/htdocs/dev.XXX.com/phpmyadmin/sql/create_tables.sql


(2)创建数据库用户
CREATE USER 'pma'@'localhost' IDENTIFIED BY 'pmapass';
GRANT ALL PRIVILEGES ON `phpmyadmin`.* TO 'pma'@'localhost' WITH GRANT OPTION;
FLUSH PRIVILEGES;


(3)配置config.ini.php文件
vim config.inc.php
/**
* phpMyAdmin configuration storage settings.
*/

/* User used to manipulate with storage */
// $cfg['Servers'][$i]['controlhost'] = '';
// $cfg['Servers'][$i]['controlport'] = '';
// $cfg['Servers'][$i]['controluser'] = 'pma';    
// $cfg['Servers'][$i]['controlpass'] = 'pmapass';

参考:
http://wlb.wlb.blog.163.com/blog/static/46741320158199711556/
http://bbs.vpser.net/thread-13962-1-1.html
像discuz论坛啥的, 要是楼数多,分页发现有这个问题,导致mysql的cpu负载较高,分页需要优化,如limit 222222,20,从20万以上取这样的。
再说是对mysql的INNODB引擎进行分区,以提高mysql的性能:

资料:
【分页查询时如何优化MySQL的性能?必藏】
http://toutiao.com/group/6303291874997141762/?iid=4621176401&app=news_article&tt_from=android_share&utm_medium=toutiao_android&utm_campaign=client_share

MySQL架构优化实战系列3:定时计划任务与表分区:
http://sc.qq.com/fx/u?r=BHE7tkA

MySQL架构优化实战系列2:主从复制同步与查询性能调优:
http://blog.csdn.net/huaweitman/article/details/51822082

MySQL架构优化实战系列1:数据类型与索引调优全解析:
http://udn.yyuap.com/article-11729.html
背景:用阿里云编译mysql5.7.12时在编译一半时出现错误,如下:

[ 50%] Building CXX object sql/CMakeFiles/sql.dir/item_cmpfunc.cc.o
[ 50%] Building CXX object sql/CMakeFiles/sql.dir/item_create.cc.o
[ 50%] Building CXX object sql/CMakeFiles/sql.dir/item_func.cc.o
[ 50%] Building CXX object sql/CMakeFiles/sql.dir/item_geofunc.cc.o
c++: 编译器内部错误:已杀死(程序 cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
make[2]: *** [sql/CMakeFiles/sql.dir/item_geofunc.cc.o] 错误 4
make[1]: *** [sql/CMakeFiles/sql.dir/all] 错误 2
make: *** [all] 错误 2



不要感觉奇怪,其实是内存不够导致的,这位兄弟也遇到一样的问题,如下:
在这里特别提醒, 对于mysql5.7.8的make编译, 如果是阿里云centos主机512M内存的, 会在make编译到45%时会报错, 这是内存不足所致。

c++: Internal error: Killed (program cc1plus)
Please submit a full bug report.
See <http://bugzilla.redhat.com/bugzilla> for instructions.
make[2]: *** [sql/CMakeFiles/sql.dir/item_geofunc.cc.o] Error 1
make[1]: *** [sql/CMakeFiles/sql.dir/all] Error 2
make: *** [all] Error 2
那么设置2G交换分区来用下 :

# dd if=/dev/zero of=/swapfile bs=1k count=2048000 --获取要增加的2G的SWAP文件块
# mkswap /swapfile     -- 创建SWAP文件
# swapon /swapfile     -- 激活SWAP文件
# swapon -s            -- 查看SWAP信息是否正确
# echo "/var/swapfile swap swap defaults 0 0" >> /etc/fstab     -- 添加到fstab文件中让系统引导时自动启动
注意, swapfile文件的路径在/var/下
编译完后, 如果不想要交换分区了, 可以删除:

# swapoff /swapfile
# rm -fr /swapfile

部分摘录自:http://blog.csdn.net/cryhelyxx/article/details/47610247
背景:最近研究一下rpmbuild打的mysql最新包出现初始化mysql-5.7.12时的数据库错误,[ERROR] COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1',再涉及到mysql的密码问题居然放error.log里了。
1)init database and set password:
[root@localhost bin]#./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
2016-04-21T03:26:22.900370Z 0 [ERROR] COLLATION 'utf8_general_ci' is not valid for CHARACTER SET 'latin1'
2016-04-21T03:26:22.900452Z 0 [ERROR] Aborting
2)try directly start mysql server display:
[root@localhost bin]# ./mysqld_safe  
./mysqld_safe: line 541: /data/mysql/mysqld_safe.pid: No such file or directory
awk: (FILENAME=- FNR=1) warning: error writing standard output (Broken pipe)
2016-04-21T03:26:28.773480Z mysqld_safe Logging to '/data/logs/mysql/error.log'.
2016-04-21T03:26:28.814486Z mysqld_safe Starting mysqld daemon with databases from /data/mysql
2016-04-21T03:26:28.957913Z mysqld_safe mysqld from pid file /data/mysql/mysql.pid ended

so,tail -f ,tail -f /data/logs/mysql/error.log


乍一看,是字符编码问题,着实在my.cnf配置文件上面设置了字符编码如下:      


再启动,出现新的报错:

可能是目录的权限问题,继续在rpmbuild里写上权限....
chmod -R mysql.mysql /data/logs/mysql /data/mysql

[root@localhost bin]# ./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql  
[root@localhost bin]#

日志跟踪,敬告没有Error:
2016-04-21T03:45:21.971611Z 1 [Warning] 'user' entry 'root@localhost' ignored in --skip-name-resolve mode.
2016-04-21T03:45:21.971676Z 1 [Warning] 'user' entry 'mysql.sys@localhost' ignored in --skip-name-resolve mode.
2016-04-21T03:45:21.971712Z 1 [Warning] 'db' entry 'sys mysql.sys@localhost' ignored in --skip-name-resolve mode.
2016-04-21T03:45:21.971745Z 1 [Warning] 'proxies_priv' entry '@ root@localhost' ignored in --skip-name-resolve mode.
2016-04-21T03:45:21.972041Z 1 [Warning] 'tables_priv' entry 'sys_config mysql.sys@localhost' ignored in --skip-name-resolve mode.


立即启动mysqld_safe:
[root@localhost bin]# ./mysqld_safe
2016-04-21T03:47:08.025776Z mysqld_safe Logging to '/data/logs/mysql/error.log'.
2016-04-21T03:47:08.075873Z mysqld_safe Starting mysqld daemon with databases from /data/mysql

tail -f /data/logs/mysql/error.log 端口成功启动:
2016-04-21T03:47:08.542210Z 0 [Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version: '5.7.12-log'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution


[root@localhost bin]# ./mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

重新初始化mysql用户名及密码:
[root@localhost bin]# ./bin/mysql_install_db --basedir=. --datadir=/data/mysql --user=mysql
2016-04-21 13:18:24 [WARNING] mysql_install_db is deprecated. Please consider switching to mysqld --initialize
2016-04-21 13:18:24 [ERROR]   The data directory needs to be specified.
之前版本mysql_install_db是在mysql_basedir/script下,5.7放在了mysql_install_db/bin目录下,且已被废弃。

shell>./mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql
******mysql5.7会生成一个初始化密码,而在之前的版本首次登陆不需要登录。(我前面用的是root启动的):
[root@localhost bin]# ./mysqld_safe --user=mysql    
2016-04-21T05:24:34.317097Z mysqld_safe Logging to '/data/logs/mysql/error.log'.
2016-04-21T05:24:34.463814Z mysqld_safe Starting mysqld daemon with databases from /data/mysql

这帮孙子现在是在抽风么,网上查到这密码放哪儿是一个折腾呐,那最新版本的放哪儿了?
MySQL 5.6 中,mysql_install_db 在数据库创建的时候提供选项来生成 random password。
MySQL 5.7.4 中,可以跳过 -skip-random-password 选项来默认生成随机密码。
MySQL 5.7.5 中,还是默认生成随机密码,但是选项修改为 –insecure

摸索下看:


tail日志时发现,mysql-5.7.12最新版本的密码放在error.log里面了,我去:


[root@localhost bin]# ./mysqld_safe --user=mysql &
[1] 18730

2016-04-21T05:36:56.824891Z 0 [Note] /usr/local/mysql/bin/mysqld: ready for connections.
Version: '5.7.12-log'  socket: '/tmp/mysql.sock'  port: 3306  Source distribution

连接成功,这个新版本的msyql还真TM费劲呐:
[root@localhost ~]# mysql -uroot -p
Enter password: 7EEgNltAA1;/
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.12-log

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

强制要求你修改密码:
mysql> show databases;
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
mysql> SET PASSWORD = PASSWORD('123456');
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> create database jackTestDB;
Query OK, 1 row affected (0.00 sec)


不要密码初始化数据库的参数,参考自:https://dev.mysql.com/doc/refman/5.7/en/data-directory-initialization-mysqld.html

[1] 59478
无密码连接一下看:
[root@localhost bin]# ./mysql -uroot   //果然不需要密码就进去了
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.12-log Source distribution

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> \q

直接mysql也成:[root@localhost x86_64]# mysql
进入后密码:SET PASSWORD = PASSWORD('123456');

[root@localhost bin]# ./mysql -uroot
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
mysql> SET PASSWORD = PASSWORD('******');
Query OK, 0 rows affected, 1 warning (0.00 sec)
从另一个终端登录看下,不行了,说明直接就修改了,也就是说不用flushprivilege:
[root@localhost bin]# ./mysql -uroot
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)


首次参考:http://www.bubuko.com/infodetail-1173208.html


༒࿈背༙྇景༙྇:࿈༒STR_TO_DATE(str,format) 这是DATE_FORMAT()函数的反函数。它需要一个字符串str和一个格式字符串格式。STR_TO_DATE()返回一个DATETIME值。

开发要求,获取当月佣金,主要卡在了sql对datetime 类型的判断

先后用过4种方法如下

1.select sum('price') from rrr_order_level where active_time < "2015-09-30 00:00:00";

2.select sum('price') from rrr_order_level where timestampdiff(hour,'2008-08-08 12:00:00','2008-08-08 00:00:00') > 0

3.select sum('price') from rrr_order_level where active_time < '$EndDate' and active_time > '$BeginDate'"

4.select sum('price') from rrr_order_level where active_time between '2015-09-01 00:00:00' and '2015-09-30 00:00:00';


数据库如上

分析错误,mysql不知道对应的年月日,无法比较,采用

select sum(price) from rrr_order_level where active_time >= STR_TO_DATE('2015-09-01 00:00:00','%Y-%m-%d %H:%i:%s') and active_time <= STR_TO_DATE('2015-09-30 00:00:00','%Y-%m-%d %H:%i:%s');

完美解决问题!
背景:mysqli连接数据库,pdo连接mysql都有,这块很多老代码都是用的mysql,为此,伴随PHP7的强制升级,对mysql不再支持了。So,对mysqli这块可以研究研究是很有必要的:-),demo代码如下:

运行结果:
[root@iZ25z0ugwgtZ mysql]# php test.php
Array
(
    [0] => 001
    [1] => jackX
)
Array
(
    [0] => 001
    [1] => jackX
)
Array
(
    [0] => 001
    [1] => jackX
)

——————————————————————————————————————————————————————————————
问题一:当用localhost时出现 mysql数据库 Too many connections
出现这种错误明显就是 mysql_connect 之后忘记 mysql_close;
当大量的connect之后,就会出现Too many connections的错误,mysql默认的连接为100个,而什么情况下会出现这种错误呢?

正常的mysql_connect 之后调用 mysql_close()关闭连接
但在连接错误时,会者mysql_real_query()出现错误退出时,可能忘记mysql_close();
所以在程序return 之前一定要判断是否close(),最稳妥的方法就是在写任何函数时都只有一个出口!
还有可以通过修改mysql配置文件来加大允许连接的数量!

有时你的服务器是经常出现这样的错误呢:
错误信息如下:
Can not connect to MySQL server

Error: Too many connections
Errno.: 1040

Similar error report has beed dispatched to administrator before.

从官方文档知道linux上面编译安装的mysql默认的连接为100个
文档:http://dev.mysql.com/doc/refman/5.0/en/too-many-connections.html

mysql官方告诉我们需要修改max_connections的值,那么我们怎么去修改呢?有两种方法
1、修改配置文件文件
修改/etc/my.cnf这个文件,在[mysqld] 中新增max_connections=N,如果你没有这个文件请从编译源码中的support-files文件夹中复制你所需要的*.cnf文件为到 /etc/my.cnf。我使用的是my-medium.cnf,中型服务器配置。例如我的[mysqld]的内容如下
[mysqld]
port = 3306
socket = /tmp/mysql.sock
skip-locking
key_buffer = 160M
max_allowed_packet = 1M
table_cache = 64
sort_buffer_size = 512K
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
max_connections=1000

由于对mysql还不是很熟悉,所以很多参数没有修改。哈哈。。

2、非使用mysqld脚本自动启动的用户。
修改$MYSQL_HOME/bin/mysqld_safe文件
例如:/usr/local/mysql/bin/mysqld_safe这个文件
grep -n ‘max_connection’ $MYSQL_HOME/bin/mysqld_safe
修改对应行号的max_connections参数值

来自:http://www.2cto.com/database/201306/218126.html



问题二:当在测试时出现[root@iZ25z0ugwgtZ mysql]# php  test.php
PHP Warning:  mysqli::mysqli(): (HY000/2002): No such file or directory in /data/codesdev/testdemo/mysql/test.php on line 2
Connect failed: No such file or directory
将'localhost'修改为'127.0.0.1'之后链接正常!
当主机填写为localhost时MySQL会采用 unix domain socket连接,当主机填写为127.0.0.1时MySQL会采用TCP/IP的方式连接。使用Unix socket的连接比TCP/IP的连接更加快速与安全。这是MySQL连接的特性,可以参考官方文档的说明4.2.2. Connecting to the MySQL Server:

On Unix, MySQL programs treat the host name localhost specially, in a way that is
likely different from what you expect compared to other network-based programs.
For connections to localhost, MySQL programs attempt to connect to the local server
by using a Unix socket file. This occurs even if a --port or -P option is given to
specify a port number. To ensure that the client makes a TCP/IP connection to the
local server, use --host or -h to specify a host name value of 127.0.0.1, or the IP
address or name of the local server. You can also specify the connection protocol
explicitly, even for localhost, by using the --protocol=TCP option.
这个问题有以下几种解决方法:

使用TCP/IP代替Unix socket。即在连接的时候将localhost换成127.0.0.1。
修改MySQL的配置文件my.cnf,指定mysql.socket的位置:
/var/lib/mysql/mysql.sock (你的mysql.socket路径)。
直接在php建立连接的时候指定my.socket的位置(官方文档:mysqli_connect)。比如:
$db = new MySQLi('localhost', 'root', 'root', 'my_db', '3306', '/var/run/mysqld/mysqld.sock')
如果哪里没有说清楚或者说错了,欢迎提出了~~

来自:https://segmentfault.com/q/1010000000328531
碰到问题一:



安装了MySQL,然后用 telnet ip 3306,端口后报BHost '127.0.0.1' is not allowed to connect to this MySQL serverConnection closed by foreign host,虽然自己以前也碰到过,后来解决了,但是觉得还是值得贴出来,估计会有很多人同样碰到过,贴个解决办法:

MySQL>UPDATE MySQL.user SET Host='%' WHERE Host='localhost';  
MySQL>GRANT ALL PRIVILEGES  

这样搞如果该服务器在外网,有可能不安全,因为%的意思是谁都都可以连接的意思,最好是指定IP地址能连接,如问题二所示。

碰到问题二:


处理方法有二个
1、(如何解决客户端与服务器端的连接(mysql) :xxx.xxx.xxx.xxx is not allowed to connect to this mysql serv
) 授权法。例如,你想myuser使用mypassword从任何主机连接到mysql服务器的话。

GRANT ALL PRIVILEGES ON *.* TO ‘myuser’@'%’ IDENTIFIED BY ‘mypassword’ WITH GRANT OPTION;
如果你想允许用户myuser从ip为192.168.1.3的主机连接到mysql服务器,并使用mypassword作为密码

GRANT ALL PRIVILEGES ON *.* TO ‘root’@’192.168.1.3′ IDENTIFIED BY ‘mypassword’ WITH GRANT OPTION;
GRANT ALL PRIVILEGES ON *.* TO ‘root’@’10.10.40.54′ IDENTIFIED BY ’123456′ WITH GRANT OPTION;

2、 改表法。可能是你的帐号不允许从远程登陆,只能在localhost。这个时候只要在localhost的那台电脑,登入mysql后,更改 “mysql” 数据库里的 “user” 表里的 “host” 项,从”localhost”改称”%”
这个是因为权限的问题,处理方式如下:

shell>mysql --user=root -p
输入密码

mysql>use mysql
mysql>GRANT SELECT,INSERT,UPDATE,DELETE ON [db_name].* TO [username]@[ipadd] identified by '[password]';

[username]:远程登入的使用者代码
[db_name]:表示欲开放给使用者的数据库称
[password]:远程登入的使用者密码
[ipadd]:IP地址或者IP反查后的DNS Name,此例的内容需填入'60-248-32-13.HINET-IP.hinet.net' ,包函上引号(')

(其实就是在远端服务器上执行,地址填写本地主机的ip地址。)

也可以这样写

mysql -u root -pvmwaremysql>use mysql;mysql>update user set host = ‘%’ where user = ‘root’;mysql>select host, user from user;

分别来自:
http://database.51cto.com/art/201006/204016.htm
http://www.111cn.net/database/mysql/42040.htm
背景:由于数据库服务器安装在数据库机上,因此,在linux中只需安装mysql的客户端库就可以了。那么这个PHP下的mysql client要不要安装?再就是如果想在这台机器上连接mysql  server,客户端要不要安一个呢,当然要,且只安mysql的client客户端。
方法一:从编译好的包里释放安装:
一)有rpm包的情况:
MySQL-client-5.0.22-0.i386.rpm //mysql -uroot 这个client的一个包 标准MySQL客户程序。你可能总是需要安装这个包。
MySQL-devel-5.0.22-0.i386.rpm  //要想用c去连接这个mysql的lib库
(安装好以后,在 /usr/include/mysql/ 目录中存放有libmysqlclient的头文件mysql.h,在 /usr/lib/mysql/ 目录中存放有mysql的库文件,但只有.a结尾的(即静态库)库文件(包括libmysqlclient.a),没有.so(共享库)文件。)
键入以下命令安装:

#rpm -ivh MySQL-client-5.0.22-0.i386.rpm
#rpm -ivh MySQL-devel-5.0.22-0.i386.rpm

使用如下命令编译一个简单的测试程序(代码在本文结尾处给出):
#gcc -c -I/usr/include/mysql mysql-test.c
此命令成功生成了目标文件mysql-test.o。
继续键入以下命令。
#gcc -o --static mysql-test mysql-test.o -L/usr/lib/mysql -lmysqlclient

注意参数的顺序,gcc有时会因为某些参数顺序不对而报错,某些相关参数的具体顺序应该如何,还望高人指点。
以上命令确给出了数不清的“引用未定义符号”的错误信息,引用未定义符号的是libmysqlclient.a
带着希望折腾了许久,最后决定从源码包安装mysql客户端程序库。

卸载MySQL-client与MySQL-devel:
#rpm -e MySQL-client
#rpm -e MySQL-devel

二)yum 安装,其实是一样的,只是在网上安装,看来centos7上新的db数据库会向mariadb转的趋势啊:
[root@iZ25z0ugwgtZ logs]# yum search mysql|grep dev
mysql++-devel.x86_64 : MySQL++ developer files (headers, examples, etc.)
mariadb.x86_64 : A community developed branch of MySQL
mariadb-devel.i686 : Files for development of MariaDB/MySQL applications
mariadb-devel.x86_64 : Files for development of MariaDB/MySQL applications


方法二:从源码里通过参数只编译安装客户端:
[root@iZ25dcp92ckZ vhost]# ldconfig -v|grep mysql
/usr/lib64/mysql:  这个路径在哪儿配置的呢?在:vi /etc/ld.so.conf  自己加上想要找的动态链接库:/usr/local/inotify-tools-3.14/lib
        libmysqlclient.so.18 -> libmysqlclient.so.18.0.0
从源码包安装mysql客户端程序库。
#tar -zxvf mysql-5.0.22.tar.gz (mysql-5.0.22.tar.gz位于/root目录)
#cd mysql-5.0.22
进入mysql-5.0.22目录,阅读 INSTALL-SOURCES 文件,并看到几个关键选项:
1、--without-server
只编译安装客户端程序库,不编译mysql服务器程序,这在本机只需要libmysqlclient时很有用。

Mysql高版本用了boost和cmake(MySQL 5.5版本以后,使用CMake编译工具)参数是这样和./configure对应的,参见链接,http://www.linuxeye.com/Linux/MySQL-cmake-options.html,-DWITH_SERVER=0,总之,这个cmake有些参数不支持和configure还不太一样,这个DWITH_SERVER 是臆想出来的:


2、--enable-thread-safe-client
让libmysqlclient中的例程具有线程安全性,要编写多线程的mysql客户端程序时就少不了了,这要求本地拥有多线程库。
3、--prefix 指定安装目录
启动configure脚本:
#mkdir /usr/local/mysql
#./configure --without-server --enable-thread-safe-client --prefix=/usr/local/mysql
大概6分钟后,configure脚本生成好所有的Makefile后退出。
当前目录下执行make进行编译:
#make
这个过程除了时间长一点以外没有别的,大概一个钟头后make完成编译任务。
安装:
#make install
这个过程也比较快,约两三分钟。
安装完成以后,mysql.h文件在 /usr/local/mysql/include/mysql/目录中(这里include目录中还有一个mysql子目录)。
以lib开头的库文件在/usr/local/mysql/lib/mysql/目录中(与mysql.h的情况一样,这里lib目录中还有一个mysql子目录)。
此时再来链接测试程序的目标文件:
#gcc -o mysql-test mysql-test.o -L/usr/lib/mysql -lmysqlclient
OK,一切正常,链接成功。
执行一下:
#./mysql-test
系统这时又发出错误提示:Loading libmysqlclient.so.15 Error; No Such File!
将/usr/local/mysql/lib/mysql/目录中的libmysqlclient.so.15.0.0复制到/usr/lib/目录下:
#cp /usr/local/mysql/lib/mysql/libmysqlclient.so.15.0.0 /usr/lib/libmysqlclient.so.15
#./mysql-test
屏幕打印出:mysql_init() successed.后就不动了.
约莫90秒后打印libmysqlclient的提示信息:Can not connect to mysql server(110)
这时在windows xp的msdos控制台键入:
>netstat -na
看到了系统已经打开了3306端口,即mysql server确实在运行。
最后注意到xp中启用了系统防火墙, 禁用系统防火墙后回到linux的ppty键入:
#./mysql-test
这时,黎明的曙光终于出现了,提示信息告诉我,它已经连接上了XP中的mysql server。

以上主要参考:http://blog.chinaunix.net/uid-26466663-id-3358199.html

mysql中的两个包 libmysqlclient-devel和mysql-devel 有什么区别啊,为什么安装了mysql-devel就不能安装 libmysqlclient-devel了?
MySQL服务器。除非你只是想要与运行在其他机器上MySQL服务器连接,否则你将需要它。
背景:天峰兄弟及Swoole的出现解决了长连接问题,但对mysql的线程池还需要进一步解决成一个体系,这块web直接连, 那么连接池也就是多余的 ,RPC形成一个过程也就让性能消耗最小,非常直接且跨平台,再谈一点这块的一个背景:也包括在PHP出现前的WEB1.0阶段,如,在新浪企业邮箱就有基于Sun Solaris 系统上面用c++写Mysql的长连接实现邮箱用户验证登录,那时候的长连接是基于Solaris 下的RPC实现(那时硬件也是sun提供的),对mysql那一端形成一个远程过程的调用,通过XDR数据结构进行解析mysql传来的数据项(RPC也为sun最新提出并后来在linux上默认支持),也就是说像用户登录验证这一块用Mysql的长连接来实现,提高其效率运行相当稳定,后面这个系统迁移到了FreeBSD后,出现了mysql长连接的服务经常出现假死,也就是说进程还在,但是已经连接不上mysql了,重新启动这个RPC服务又好了,原因未知,当时我对c++不了解(现在也不太了解,只听说要看是否形成coredump啥的),当年我还写过一个判断死了就杀死,重启动,判断的程序也老半天回不来,于是我又改成了一个多线程,如果超时没有回来,就干掉那个进程,重启Rpc服务,再后来,这套C++的cgi被替换成了php,再后来基于FreeBSD的系统迁移到了Linux,也就是现在一直在linux上,linux也就强大了起来,回想起来,当年一个登录服务如此极致,现在都变成了直接查询mysql了,这个长连接技术有还有用吗?我只能说对有上千台上万台的服务器可能有用,能节省一定的机器成本罢。但是,追求技术永无止境,需要有这样的一些东西来繁荣我们这个PHP的市场,长连接这个话题不再是Java做成了连接池,像c++也能做成连接池,像腾讯广平就有c++团队还有写cgi实现长连接Mysql服务,据说前二年吧更多关注了H5,像实时技术,比如Tail技术在web上的实现,有转向nodejs的趋势(node试想通过在google这颗大树下提供出来的V8引擎让前端程序员为排头兵统一后端服务及接口),而此时的PHP拿不出这样的技术,是很危险的,有了swoole起到填补作用,我更多的是觉得官方应该重视这个技术,而不是形成一个扩展,像H5的来到,像websocket的进入,这些东西对于Node来讲,从前端向后端的统一,而PHp呢?没有谁来解决,那么从用户角度来讲,开发者用户的流失或迁移,对PHP本身也是一个损失,但我还是说PHP是最好的语言没有之一,期望其能伴随潮流,与时俱进,更好满足当前web端新的需求。

发牢骚:port其实是通过源码编译的,所以不好。FreeBSD这不是都提供了嘛,还要怎么的,有点像人们的皮带,一天不系,你觉得不舒服,要勒紧吗?现代这帮人典型的吃现成的,导致了FreeBSD的没落。
源码包自然有必要提供, 但是你不能要求每个用户用一个软件都编译半天吧,源码的好处是只要你微调得当,性能是最大化的
,然并卵,现在机器性能都挺好,还有8M的嵌入式没法支持,什么不支持,我是发现还有比我懒的人了,听说有交叉编译也不会是在8M上编译啊。

前企业邮箱杀rpc的shell,都快忘记了,做个备份: http://jackxiang.com/post/1273/   2008-9-23 18:31 八年前的事情了。
从Solaris 到FreeBSD再到linux(Centos),其最后居然是linux 居上,而像sun的java被收购,最后FreeBSD的开源太底层(基于系统OS开源),BSD 的代码不是被控制在任何一个人手里,而 Linux的内核基本上被 Linus Torvalds ( Linux创始人)所控制,BSD 并没有单一的人来说什么可以或什么不可以进入代码。但BSD太自由了难度反而大了,人少了是根本原因,再就是商业化的需求没有满足到,被linux干下坡路了,但是,Debian Linux操作系统创始人去世 年仅42岁 ....,我想这个事件会给linux带来不可估量的损失,为什么,debian linux向FreeBSD学习port技术后,发展出的ubutu系统..不说了,反上这个哥们算是能善于学习,他死了...linux社区未来不太好说,但会有波澜是肯定的了。
————————————————————————————————————————————————————————————————
PHP的数据库连接池一直以来都是一个难题,很多从PHP语言转向Java的项目,大多数原因都是因为Java有更好的连接池实现。PHP的MySQL扩展提供了长连接的API,但在PHP机器数量较多,规模较大的情况下,mysql_pconnect非但不能节约MySQL资源,反而会加剧数据库的负荷。

假设有100台PHP的应用服务器,每个机器需要启动100个apache或fpm工作进程,那每个进程都会产生一个长连接到MySQL。这一共会产生1万个My SQL连接。大家都知道MySQL是每个连接会占用1个线程。那MYSQL就需要创建1万个线程,这样大量的系统资源被浪费在线程间上下文切换上。而你的业务代码中并不是所有地方都在做数据库操作,所以这个就是浪费的。

连接池就不同了,100个worker进程,公用10个数据库连接即可,当操作完数据库后,立即释放资源给其他worker进程。这样就算有100台PHP的服务器,那也只会创建1000个MySQL的连接,完全可以接受的。

首先,环境约定如下:
说一下测试环境吧:OS CentOS 7.1 x86;PHP 5.4.44;Mysql 5.7.9-log;swoole-1.7.22。

一)开始编译,网上好多都是编译过了,但是出现某些函数找不到运行时会警告,特别标名一下原因:
以前确实没有好的办法来解决此问题的,现在有了swoole扩展,利用swoole提供的task功能可以很方便做出一个连接池来。
编译时要注意一下:

还是出现:[2015-06-29 18:58:24 *9092.0] WARN zm_deactivate_swoole: Fatal error: Call to undefined function swoole_get_mysqli_sock()
因为参数:编译swoole时需要加enable-async-mysql参数来开启 swoole_get_mysqli_sock

php -r "print_r(get_defined_functions());"|grep swoole_get_mysqli_sock 并没发现有这个函数~可能新版本移掉了吧。
实践发现,这块swoole的官方对这块的编译参数并不太提及,不是没有这个函数,这个swoole_get_mysqli_sock函数通过源码里发现是有的。
是因为configure里出现了问题,出现在这儿,对比一下编译且运行Ok的./configure选项就知道了,正确的如下:

一些博文里的:--enable-async-mysql 后面有路径,这块在swoole-src-swoole-1.7.22-stable里是没有这个路径反而编译正确了。
————————————————————服务端的代码贴在这儿—————————————————————————————
代码如下:


rango有一个更详细的连接池服务端的代码放这儿了:
http://rango.swoole.com/archives/288

二)客户端代码如下:


三)运行一下看有没有返回:
[root@iZ25dcp92ckZ mysql.swoole.com]# php  mysqlSwooleCli.php
string(292) "array (
  0 =>
  array (
    'linkid' => '3',
    'linkname' => '猪头党乐园',
    'linkurl' => 'http://www.gipsky.com/',
    'linklogo' => '',
    'linkdesc' => '',
    'linkgptoid' => '19',
    'linkorder' => '3',
    'isdisplay' => '1',
    'empty1' => '',
    'empty2' => '',
  ),
)
"

最后,这个到底是不是真长连接在mysql这儿了呢?我们验证一下,连接mysql看下:


还有问题?优化如下,我提出我为何要坚持引入RPC的原因:
摘录来自:http://bokjan.com/prog/php-db-conn-pool-with-swoole.html  现在没了。
现在可以运行了,本次实验是成功的。但是如果使用dbcp_query()这个函数,每次调用都要发起一次TCP连接,执行的语句多了,肯定出问题。这个时候我们就可以把它封装成一个类了,单纯实现这个会比较的简单,但是打出来要点时间,这里就不写了。

我的看法:对于这位兄弟提到的每次调用都要发起一次TCP连接,而这个问题在RPC里直接供给前端WEB会得到很好的解决,为什么呢?
目前这种搞法是:一个web请求来到服务器后,这个服务器再生成一个连接swoole的连接池的端口,这儿是:9508端口它再去长连接Mysql的3306端口。
那么,如果每次来一个用户这个9508就会再进去一个连接,再到Mysql的3306接口,这块这个9508取到数据完后,销毁这个socket的fd句柄,来得越多,
这个是不是就会出现很多句柄在这儿生生死列,也就是上面这个兄弟讲的每次调用都要发起一次TCP连接,执行的语句多了,肯定出问题。不是封装的事,
而这种架构在我看来本来就有问题,为此,我提出我的一个引入RPC的看法,以解决每次都生生死死的效率问题,思路如下:
这块RPC引入带来了额外的XDR兼容跨平台的数据接口的打包、解包、返回同样需要打包,再到客户端揭包的一个客外的socket数据流量,不是RPC最大8K性能问题所在。
架构如下:在每台服务器上的RPC服务器上启动一次性多个RPC,每个RPC连接一个Mysql的长链接,而rpc的client直接放到Apache/nginx的cgi目录下,这样从
Web端传过来的请求,直接通过WEB传到RPC服务器器直达Mysql,而这个RPC服务服务这块并不需要重新销毁重新生成请求,有更多连接过来只是再多起几个RPC的server(同时Mysql的长连接也多了几个),也就是说通过RPC的Client与RPC的Server长连接类似KeepAlive,直接打通了Mysql数据库,这样提高了效率,因为这个连接池不管怎么样,都需要给web端来访问,当前解决的就是web端用户一下就来了很多人的一个问题,还形成了可扩展的一个Client和Server模型。
总之的总之,Rpc调用远程就像调用一个函数一样,避免了重新销毁重新生成请求的一个消耗,也避免了下面的serialize和unserialize的一个性能问题,也就真正实现了最大化性能和架构可扩展的解决方案,也就是为何我建议加一个RPC功能,把底层做到极致,通过简单配置就能打通Mysql的各个表结构。

最后:今天做的是数据库连接池的实现。从上面的代码我们可以看见,程序与连接池之间的数据交换是使用php序列进行的。这里会有两次的serialize、unserialize,绝对也是一个开销。Rango的文章里面有说到“MySQL是每个连接会占用1个线程……大量的系统资源被浪费在线程间上下文切换上……不是所有地方都在做数据库操作,所以这个就是浪费的。”再看看他那篇文章的假设:“假设有100台PHP的应用服务器,每个机器需要启动100个apache或fpm工作进程。”这肯定不是一个小项目,确实就适合用连接池了。写的东西是用来练手或者解闷儿的?常规方法已经可以了。不要忘了一点:程序与连接池的交互我们应该还是用Swoole实现的,Swoole可是一个TCP/UDP扩展。而Swoole只能运行在Linux平台上面,但是Linux平台上的MySQL是可以用UNIX Socket通讯的。

来自:http://rango.swoole.com/archives/265
http://bokjan.com/prog/php-db-conn-pool-with-swoole.html
背景:升级了一下mysql到最新版本 5.7.9,博客数据没有动,后导出数据备份时出现Couldn't execute 'SHOW VARIABLES LIKE 'gtid\_mode'',加上 --set-gtid-purged=off出现新错误的问题,总之一堆问题,最后还是终于导出了,特别是升级后一定要重启,啥玩意,艹。
实践如下,出现问题:
[root@iZ25dcp92ckZ backup]# mysqldump -uroot -p -ujustwinit_mysql_database > -ujustwinit_mysql_database.cn.sql
Enter password:
mysqldump: Couldn't execute 'SHOW VARIABLES LIKE 'gtid\_mode'': Table 'performance_schema.session_variables' doesn't exist (1146)




用mysqldump备份时出现下面的出错信息:
mysqldump:Couldn't execute  ‘SELECT @@GTID_MODE':Unknown system variable 'GTID_MODE' (1193)
造成此错误的原因是因为5.6引入了Global Transaction Identifiers (GTIDs) 。GTIDs可以让主从结构复制的跟踪和比较变得简单。mysqldump会试图查询这个系统变量,但这个变量在5.6之前的版本中不存在,所以产生错误。解决的方法很简单,在mysqldump后加上–set-gtid-purged=OFF命令
如:
mysqldump -h(主机名或ip) -u(用户名) -p(密码) 数据库名 --set-gtid-purged=off >d:/db.sql

From:http://www.rjkfw.com/s_3139.html
___________________________________________________________________

[root@iZ25dcp92ckZ ~]#  mysqldump  --set-gtid-purged=off -uroot -p -ujustwinit_mysql_database > -ujustwinit_mysql_database.cn.sql
Enter password:
mysqldump: Couldn't execute 'SHOW VARIABLES LIKE 'ndbinfo\_version'': Table 'performance_schema.session_variables' doesn't exist (1146)
解决办法:
[root@iZ25dcp92ckZ ~]# mysql_upgrade -u root -p --force
Enter password:
Checking server version.
Running queries to upgrade MySQL server.
Checking system database.
mysql.columns_priv                                 OK
mysql.db                                           OK
。。。。。。
sys.sys_config                                     OK
temperature.temperature                            OK
temperature.tempsetting                            OK
Upgrade process completed successfully.
Checking if update is needed.

再次导出:
[root@iZ25dcp92ckZ ~]#  mysqldump  --set-gtid-purged=off -uroot -p -ujustwinit_mysql_database > -ujustwinit_mysql_database.cn.sql
Enter password:
mysqldump: Couldn't execute 'SHOW VARIABLES LIKE 'ndbinfo\_version'': Native table 'performance_schema'.'session_variables' has the wrong structure (1682)

忘记重启了,于是重启下,再次导出,出现新的错:
[root@iZ25dcp92ckZ bin]#  mysqldump  --set-gtid-purged=off -u-ujustwinit_mysql_database_mysql_database -p -ujustwinit_mysql_database_mysql > -ujustwinit_mysql_database.cn.sql
Enter password:
mysqldump: Got error: 1044: Access denied for user '-ujustwinit_mysql_database_mysql'@'localhost' to database '-ujustwinit_mysql_database_mysql' when using LOCK TABLES

用mysqldump备份数据库时出现when using LOCK TABLES_:
--skip-lock-tables
普通用户备份mysql 数据库报错

mysql 无lock tables权限 报Access denied for user 'dbuser'@'localhost' to database 'db' when using LOCK TABLES

主要原因是该用户无lock tables 该权限,处理办法:

1. 给该普通用户赋予lock tables 权限,建议是删除该用户,重新用mysql命令建

2. 加上--skip-lock-tables即可

mysqldump -udbuser -p dbname --skip-lock-tables > dbname.sql


3. 使用root 备份


MySQL无lock tables权限 报Access denied for user when using LOCK TABLES:
http://www.linuxidc.com/Linux/2012-01/51802.htm

mysqldump  --set-gtid-purged=off --skip-lock-tables -u-ujustwinit_mysql_database_mysql_database -p -ujustwinit_mysql_database_mysql > -ujustwinit_mysql_database.cn.sql

成功了:
[root@iZ25dcp92ckZ bin]# mysqldump  --set-gtid-purged=off --skip-lock-tables -uroot -p justwinit_mysql_database  > jackxiang.com.database.bak.perfected.2015.12.29.sql
Enter password:



来自:http://www.amznz.com/error-native-table-performance_schema/


背景:作者的服务器之前是Windows的后迁移到linux上,发现SQL查询的表在Linux上对大小写敏感,出现找不到该表,如何不改变服务器的表名称为对应的小写或代码改大写就能做到呢,改下my.cnf即可做到,如下摘录。
为什么在Windows能正常运行的程序和数据库,在Linux就会出现问题呢。这时一般会怀疑系统环境的问题,因为程序和数据库是一样的。
然而其实是英文字母大小写导致的结果。
比如在首页调取数据库数据的SQL文如下。
SELECT user_name,id from User;
User表在Windows系统上的Table名为user,因为不区别英文字母大小写所以没问题。
而在Linux会怎么样呢?
迁移过来的Table名是user,而在SQL文里指定的是User表。别忘了这家伙(Linux)区别英文字母大小写,因此会提示该表(User表)不存在。
解决方法
大概有3种解决方法,第一个是修改数据库的Table名,第二个是修改程序,第三个是修改MySQL的参数。
第一和第二,就无需多做说明了,而第三种方法是利用MySQL参数lower_case_table_names。
lower_case_table_names
参数lower_case_table_names是,在MySQL里怎么区别Table英文字母大小的,默认是0。
0:区别大小写1:不区别大小写(Table名以小写保存)2:不区别大小写(Table名以原来的大小写保存)
这样一来就简单了,可以让MySQL不区别Table名的大小写。在/etc/my.cnf(yum安装时的默认路径)文件的[mysqld]下面添加lower_case_table_names = 1就可以了。
[mysqld]
...
lower_case_table_names = 1
...
修改MySQL参数之后,重启一下数据库。

来自:http://m.toutiao.com/i6223691155964428802/?tt_from=android_share&iid=3283494589&app=news_article&utm_medium=toutiao_android&utm_campaign=client_share
背景:一外包项目其字段名为order,且是字符串,还order by order,这样的一个搞法,为此,这块Mysql通过sql排序是有问题的,因为里面存的是整数,这块直接修改表为整数也就Ok了。
MySQL字符串相信大家都不陌生,在MySQL字符串排序时经常会遇到一些问题,比如下面的这
今天解决了一个关于MySQL字符串排序的很奇怪的问题,在数据里面定义的是varchar类型,实际存放的是Int类型的数据,按一下查询语句进行排序:
将字段*1或者+0可以将MySQL字符串字段按数值排序
如:
select * from table where 1 order by id*1 desc;
或者
select * from table where 1 order by id+0 desc;
除了上述方法外,这里附上一种排序方法,利用find_in_set()进行无敌排序
附上Mysql函数 find_in_set() 的用法:
-------------------------------------------------------
举个例子来说:
有个文章表里面有个type字段,他存储的是文章类型,有 1头条,2推荐,3热点,4图文 .....11,12,13等等
现在有篇文章他既是 头条,又是热点,还是图文,
type中以 1,3,4的格式存储.
们我们如何用sql查找所有type中有4图文标准的文章呢??

这就要我们的find_in_set出马的时候到了.
以下为引用的内容:
select * from article where FIND_IN_SET('4',type)
FIND_IN_SET(str,strlist)
Returns a value 如果字符串 str 在由 N 个子串组成的列表 strlist 中,返回一个 1 到 N 的值。一个字符串列表是由通过字符 “,” 分隔的多个子串组成。如果第一个参数是一个常数字符串,并且第二个参数是一个 SET 列类型,FIND_IN_SET() 函数将被优化为使用位运算!如果 str 在不 strlist 中或者如果 strlist 是一个空串,返回值为 0。如果任何一个参数为 NULL,返回值也是 NULL。如果第一个参数包含一个 “,”,这个函数将完全不能工作:
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
-> 2
for example:
$sql = "select p.*, find_in_set(p.products_id,$string_hot_pid) as rank from products p where p.products_id in ($string_hot_pid) order by rank";
大家有什么好的想法和建议可以留下宝贵的意见 以便共同进步
来自:http://www.cnblogs.com/yhyjy/archive/2012/07/25/2607818.html
http://1055592535.iteye.com/blog/1674734
背景:Raspberry Pi下的mysql启动出现如下:
151017  8:33:10 [Note] Server socket created on IP: '127.0.0.1'.
151017  8:33:10 [ERROR] Can't start server: Bind on TCP/IP port: Cannot assign requested address
151017  8:33:10 [ERROR] Do you already have another mysqld server running on port: 3306 ?


注意关键词 Bind
  这时,可以打开/etc/mysql/my.cnf
  ...
  bind-address  = 192.168.141.25
  ...
  如果你也是这么写的,那么把它改成
  bind-address  = 0.0.0.0
  然后重启即可
  另外,mysql在启动时进行了端口的bind,那么当ip更换时,请注意这些细节

vi /etc/mysql/my.cnf

#bind-address           = 127.0.0.1
bind-address            = 0.0.0.0

来自:http://www.educity.cn/wenda/403390.html

实际情况是因为自己把lo给干掉了,没有127.0.0.1这个端口:
vi /etc/network/interfaces
auto lo
iface lo inet loopback
....

同理,apache2也是一样的道理,因为这个软的IP,没有了,于是也没法访问,得特别注意:
vi /etc/network/interfaces
背景:有时一些小的网站,比如个人博客需要每天备份数据,鉴于此,得自动化不是,这儿就是一个简单可行的好方法,配置上后就不用管了。更牛B点就是主辅助同步,在辅库上运行下面的脚本更发妥当。
1)备份权限列表需要哪些?
1.Select  读取
2.SHOW DATABASES 允许访问完整的数据库列表
4. LOCK TABLES 允许锁定表
5.RELOAD 允许载入和刷新服务器缓存
以上几点是必须的.请注意
主辅助是不复制角色表的。

2)实践添加备份用户如下:
grant SELECT, RELOAD, SHOW DATABASES, LOCK TABLES on *.* to 'back'@'localhost' identified by "************"

3)实现下面自动备份脚本:
cat backUpJustWinDatas.sh


4) 定时生成定时删除命令:
1)定时生成:
0 0 * * * /bin/bash /usr/local/scripts/backUpJustWinDatas.sh
2)删除旧的:
0 1 * * * find /data/backup/db.JustWin.com -mtime +7 -exec rm -R {} \;

最后,参考实践来源自:http://www.jb51.net/article/49099.htm
http://blog.163.com/o5655@126/blog/static/166742834201181393837133/
阿里有卖这玩意,有的是自己运维搞,放这儿备案下:
如何选择你的RDS:
http://help.aliyun.com/knowledge_detail.htm?knowledgeId=5989703
如何快速平稳的迁入RDS:
http://hidba.org/?p=899
http://hidba.org/?p=919
http://hidba.org/?p=929
http://hidba.org/?p=941
关系数据库:除了上面说的Facebook的MySQL的例子,PCIe闪存SSD卡通过缓存(又名读缓存)写入的功能也非常有利于关系数据库。热文件、索引、元数据都可以被放置在SSD中作为缓存使用。数据也可以被放置其中。当有查询、排序和计算操作时,数据库反应速度可以成倍地增加。

facebook的MySQL数据库使用FusionIO公司的IODrive PCIe闪存卡。使用这种闪存卡来代替传统的HDD,Facebook就可以关闭MySQL的低效冗余日志系统,并且能充分利用FusionIO的记录系统。通过结合PCIe闪存与较少的写入量,与同等HDD存储相比,可以将数据存储量减少50%,并降低50%的延迟,还能增加33%的吞吐量。从Facebook的角度来看,他们降低了存储基础设施和成本的投入,因为他们的客户获得了更快的响应时间。


推动PCIe/NVMe标准化和做更多的固态硬盘产品和解决方案仍然是见效非常快的角色

摘自:http://stor.zol.com.cn/386/3865458.html
分页: 2/6 第一页 上页 1 2 3 4 5 6 下页 最后页 [ 显示模式: 摘要 | 列表 ]