macos

brew install mysql
brew reinstall mysql

brew services info mysql
# 启动数据库
brew services restart mysql

docker

# docker run --rm anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/mysql:8.0.30-8.6
mkdir -p ~/data0/store/docker_volumn/mysql
docker pull docker.io/mysql:8.4.2
docker run \
    --name mysql \
    -e MYSQL_ROOT_PASSWORD=123456  \
    -v ${HOME}/data0/store/docker_volumn/mysql:/var/lib/mysql \
    -p 3306:3306 \
    -d \
    docker.io/mysql:8.4.2


docker stop mysql
docker start mysql
mysql --host=127.0.0.1 --port=3306 --user=root --password=123456 --execute='select 1+2'

# https://github.com/sakiladb/mysql
mysql --host=127.0.0.1 --port=3306 --user=root --password=123456 < 1-sakila-schema.sql
mysql --host=127.0.0.1 --port=3306 --user=root --password=123456 < 2-sakila-data.sql


# JDBC 链接 : jdbc:mysql://localhost:3306/?allowPublicKeyRetrieval=true&useSSL=False

系统信息

-- 显示mysql的版本
SELECT VERSION();
SHOW VARIABLES LIKE 'version';
SHOW VARIABLES LIKE '%version%';

JSON

过滤

# 对象: 按照单个字段值过滤。
## 返回 1
SELECT JSON_CONTAINS('{"a": 1, "b": 2, "c": {"d": 4}}', '1', '$.a');
## 返回 1
SELECT JSON_CONTAINS('{"a": 1, "b": 2, "c": {"d": 4}}', '1', '$.b');

# 对象: 按照多个字段过滤
## 返回 1
SELECT JSON_CONTAINS('{"a": 1, "b": 2, "c": {"d": 4}}', '{"a": 1, "b": 2}', '$');
## 返回 1
SELECT JSON_CONTAINS('{"a": 1, "b": 2, "c": {"d": 4}}', '{"d": 4}', '$.c');

# 数组
## 返回 1
SELECT JSON_CONTAINS('[111,"aaa",{"d": 4, "e":5}]', '111', '$');
## 返回 1
SELECT JSON_CONTAINS('[111,"aaa",{"d": 4, "e":5}]', '"aaa"', '$');
## 返回 1
SELECT JSON_CONTAINS('[111,"aaa",{"d": 4, "e":5}]', '{"d": 4}', '$');

# 报错: "In this situation, path expressions may not contain the * and ** tokens."
SELECT JSON_CONTAINS(
    '{"branchs":[{"branch":"master1","siteList":["site1","site2"]},{"branch":"master2","siteList":["site3","site4"]}]}', '"site4"', '$.branchs[*].siteList');

# 而使用 JSON_CONTAINS + JSON_EXTRACT 的这个case 则不行的
SELECT JSON_CONTAINS(
    JSON_EXTRACT(
        '{"branchs":[{"branch":"master1","siteList":["site1","site2"]},{"branch":"master2","siteList":["site3","site4"]}]}',
        '$.branchs[*].siteList'
    ),
    '"site4"'
);
#- 返回 0,因为 JSON_CONTAINS 只检查顶层是否包含该值,不会递归查找
SELECT JSON_CONTAINS('[["site1", "site2"], ["site3", "site4"]]', '"site1"');

# 可以使用 JSON_SEARCH
select JSON_SEARCH(
    '{"branchs":[{"branch":"master1","siteList":["site1","site2"]},{"branch":"master2","siteList":["site3","site4"]}]}', 'one', 'site4', NULL, '$.branchs[*].siteList[*]') IS NOT NULL;

字段提取

--
SELECT JSON_EXTRACT('[10, 20, [30, 40]]', '$[1]');

7788

-- 返回值是 NULL(SQL 中的 NULl)
SELECT JSON_QUOTE(null);
-- 返回值是 `"null"`
SELECT JSON_QUOTE('null');
-- 返回值是 `"aaa"`
SELECT JSON_QUOTE('aaa');
-- 返回值是 `"[1,2, 3]"`
SELECT JSON_QUOTE('[1,2, 3]');

-- 返回值是 `null`
SELECT JSON_UNQUOTE('null');
-- 返回值是 `false`
SELECT JSON_UNQUOTE('false');
-- 返回值是 `aaa`
SELECT JSON_UNQUOTE('"aaa"');
-- 返回值是 `[1,2, 3]`
SELECT JSON_UNQUOTE('[1,2, 3]');

The last packet successfully received from the server was xxx milliseconds ago

SHOW GLOBAL VARIABLES LIKE '%wait_timeout%';
interactive_timeout: 指的是mysql在关闭一个交互的连接之前所要等待的秒数,
wait_timeout: 指的是mysql在关闭一个非交互的连接之前所要等待的秒数

left join

select u.id, count(IFNULL(l.user_id , 0) )
FROM user u
left join logins l on u.id = l.user_id
group by u.id;

select u.id,
    count(l.user_id)
from user u
left join logins l on u.id = l.user_id
group by u.id

函数

日期

-- %Y : 年
-- %m : 月
-- %d : 日
-- %H : 时
-- %i : 分
-- %S : 秒
select DATE_FORMAT(date,'%Y%m%d')

字符串

-- 字符串连接, 结果=aabbcc
select CONCAT('aa', 'bb', 'cc')

-- 结果=1
select FIND_IN_SET('java', 'java,c++')
-- 结果=0, 因为有空格
select FIND_IN_SET('java', 'java,c++')
-- 结果=0, 因为不是全匹配
select FIND_IN_SET('java', 'javascript,c++')

-- 使用正则,结果=1
select 'java,c++' REGEXP '(^|,)java(,|$)';

文本长度

CHAR(M)         -- 定长字符串。 M 取值范围 [1,255], 如果实际字符串小于M则会空格填充。
VARCHAR(M)‌      -- 变长字符串。 M 取值范围 [1,65535]
TINYTEXT        -- 最长= 2^8-1 =        255 字符
TEXT            -- 最长=2^16-1 =      65535 字符
MEDIUMTEXT      -- 最长=2^24-1 =   16777215 字符
LONGTEXT        -- 最长=2^32-1 = 4294967295 字符