Mysql必知必会

今天在v2ex看到有人问怎么建表,其实建表个人总结起来非常简单。

用面向对象方法建立表

class = table
object = row
property = field

如:(我习惯用单数,你可以用复数)

book:
id
title,
isbn

category:
id
name

book_category:
id
book_id
author_id

处理表关联关系

  • A1 对多 B:B 表加 a_id,比如 order_item 表加 order_id
  • A1 对 1B:附表加主表 id,比如 profile 表加 user_id
  • A 多对多 B:C 表关联 A,B,如 post_tag 表加 post_id 和 tag_id

如何建立索引(全文索引)

  • 通常常用的where条件增加索引,如select id,title from post where forum_id=3,这时候需要给forum_id加索引,ID是主键是不要加的,title也不要加
  • 数据库模糊查询(如搜索“Mysql 数据库”)需要建立全文索引(参考我的另外一篇文章:Mysql中文全文索引(含实例5分钟上手)
  • 排序可以加组合索引,如select id,title from post where forum_id=3 order by create_time desc,这时候可以加forum_id+create_time的组合索引,Mysql高版本组合索引可以设置排序
  • 组合索引单独查后部分不起作用,如上面的forum_id+create_time的组合索引,如果你只根据create_time查那么不起作用
  • 唯一字段可以加唯一索引

Mysql性能工具

  • explain可以分析sql性能,每个字段的含义都需要清楚
  • slow query log:Mysql的配置中开启慢速查询日志,慢速查询日志需要用慢查询分析工具来分析,不是用肉眼来看的
  • show full processlist可以查看当前数据库运行的查询
  • infomation_schema有一大堆有用东西

其他

  • null还是0:建议采用null表示没有,这样不会影响数据库的约束

有用的资源

大决战–企业做了有风险,不做风险更大

大决战的目标就是回答这样一个问题:我们自己在哪一块能够做到独一无二,能够做到应该说没有替代者,在这块是最卓越的最优秀的。

而要拿到第一,我们就要组织资源实现一次大决战,要夺取一个山头,夺取一个高地,企业才能确保能够生存下去。

所以两个定位之间还不能说这个是主要,那个是次要。主要还是次要其实是关乎到企业的一套战略,取决于哪一位企业家能把这个定位做得更大。

如果现在这个市场没有一个绝对的主导者、同时千军万马又在竞争的时候,这时候谁能把这个行业和老大位置先给占了,成为品类的代表,这就是一个主定位,那这种机会其实在中国尤其有价值。

所以您提到的这个视角就可以解释为什么我们那么多老字号随风而去,他们就是没有理解这个时代是需要一场大决战,在社会上把这个位置奠定起来,而不仅仅是我有好的传承我有好的工艺做法就够了。

所以为什么需要大决战,大决战的终极目标就是我要捷足先登。

邓德隆:我觉得就是每一位企业家恐怕首先要思考一个问题,如果我们一旦出手没有把握把这个山头拿下,那我还不如不出手。

王波明:所以您说这个大决战,就意味着要集中兵力打歼灭战,不能像过去那个传统的打法,一年又一年去推。

所以概括起来就是正确的位置,然后是恰当的兵力和恰当的节奏,主要取决于这三个要素。

此外,恐怕企业自己必须明白一个道理,就是说风险它是相对的,而不决战的风险更大。如果不能通过大决战去主导一个山头的话,企业就会什么都没有,风险是最大的。

首先就是大决战它肯定本身就是蕴含着风险的,不过我们可以降低风险。这里面还是有很多讲究的,我们有很多原则,比如要在测试成功的地方推动大决战,就像咱们国家改革开放,先深圳试点成功了,我再在全国推开嘛,承包责任制在小岗村试验成功了,我再在全国推开,等等。

现在企业靠守是守不住的,所以企业家如果想清楚这个问题,他就会明白必须要展开一场大决战。

没有赢家的消耗战最危险

企业家要敢于去做老大,当然这不意味着大决战就完全结束了,而是说第一阶段结束了。

所以做企业它是一个永不停止的大决战,没有终点的,这一点和战争不同,它有个终点。

参考

公众号回复小技巧

用户点击后自动触发回复

<a href="weixin://bizmsgmenu?msgmenucontent={{自动回复内容}}&msgmenuid={{自己维护一个不重复的 ID}}">{{自动回复内容}}</a>

file

回复小程序超链接

 <a data-miniprogram-appid="wx5ba8812bdfc7741f" data-miniprogram-path="amouse_wxapp_card/pages/card/home/home" href="http://www.qq.com">5万运营都在用的 运营名片小程序</a>

file

发送小程序卡片(要求小程序与公众号已关联)

参考:(https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Service_Center_messages.html#7

{
    "touser":"OPENID",
    "msgtype":"miniprogrampage",
    "miniprogrampage":
    {
        "title":"title",
        "appid":"appid",
        "pagepath":"pagepath",
        "thumb_media_id":"thumb_media_id"
    }
}

file

如何获取和设置打印机私有驱动配置参数

大部分打印机都有自己的私有驱动,私有驱动的参数都是二进制的,无法被识别,但是还是可以通过一些办法获取和保存。

参考

如何在/etc/hosts里面包含另外一个文件

hosts文件是不允许包含其他文件的,但是可以通过其他方案实现:

脚本合并方法

保存一个hosts.base一个hosts.local,然后通过脚本合并成为hosts文件

搭建本地私有dns服务器

通过bind搭建私有服务器

运维工具同步

通过pssh, ansible 等运维工具同步配置,可以和方法一一起用

参考

使用 WSL 作为开发环境 (Ubuntu+PostgreSQL+MariaDB/Mysql+PHP+Python+NodeJS+镜像安装)

安装后配置

修改DNS

/etc/resolv.conf

nameserver 223.5.5.5

修改软件源

一般情况下,将 /etc/apt/sources.list 文件中 Ubuntu 默认的源地址 http://archive.ubuntu.com/ 替换为 http://mirrors.ustc.edu.cn 即可。

可以使用如下命令:

sudo sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list

更新包

sudo apt update
sudo apt upgrade

PostgreSQL

新增apt源配置

新增配置文件 /etc/apt/sources.list.d/pgdg.list,内容:

deb https://mirrors.ustc.edu.cn/postgresql/repos/apt/ focal-pgdg main

bionic可以换成去其他版本号

导入key并安装

wget --quiet -O - https://mirrors.ustc.edu.cn/postgresql/repos/apt/ACCC4CF8.asc | sudo apt-key add -
sudo apt-get update
sudo apt install postgresql-12
sudo systemctl enable postgresql
sudo service start postgresql

创建数据库以及账户

切换到postgres用户并运行psql

sudo -u postgres psql

创建数据以及用户账户

CREATE USER c4ys WITH PASSWORD 'c4ys';
CREATE DATABASE c4ys OWNER c4ys;

MariaDb

下载key

sudo apt-get install software-properties-common
sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc'
sudo add-apt-repository 'deb [arch=amd64,arm64,ppc64el] https://mirrors.ustc.edu.cn/mariadb/repo/10.5/ubuntu focal main'
sudo apt update
sudo apt install mariadb-server

将源配置修改到单独文件

系统会自动在source.list增加配置,可以将配置移动到单独文件

/etc/apt/sources.list.d/MariaDB.list

deb [arch=ppc64el,arm64,amd64] https://mirrors.ustc.edu.cn/mariadb/repo/10.5/ubuntu focal main
# deb-src [arch=ppc64el,arm64,amd64] https://mirrors.ustc.edu.cn/mariadb/repo/10.5/ubuntu focal main

自动启动

sudo systemctl enable mariadb
sudo service mariadb start
sudo mysql_secure_installation

Python

将python3作为默认Python

sudo apt install python-is-python3  python3-pip

PHP+NGINX

sudo apt install nginx nginx php-cli php-dev php-mbstring php-mbstring  php-intl php-xml php-redis php-gd php-fpm php-curl php-bcmath php-zip -y

NPM+NGINX

sudo apt install npm

参考

PHP实现姓名和手机号星号*替换

实现mb_substr_replace

   function mb_substr_replace($string, $replacement, $start, $length = null, $encoding = null)
    {
        if (extension_loaded('mbstring') === true) {
            $string_length = (is_null($encoding) === true) ? mb_strlen($string) : mb_strlen($string, $encoding);

            if ($start < 0) {
                $start = max(0, $string_length + $start);
            } else if ($start > $string_length) {
                $start = $string_length;
            }

            if ($length < 0) {
                $length = max(0, $string_length - $start + $length);
            } else if ((is_null($length) === true) || ($length > $string_length)) {
                $length = $string_length;
            }

            if (($start + $length) > $string_length) {
                $length = $string_length - $start;
            }

            if (is_null($encoding) === true) {
                return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length);
            }

            return mb_substr($string, 0, $start, $encoding) . $replacement . mb_substr($string, $start + $length, $string_length - $start - $length, $encoding);
        }

        return (is_null($length) === true) ? substr_replace($string, $replacement, $start) : substr_replace($string, $replacement, $start, $length);
    }

用户名星号替换

替换样例:

  • 马克思:马*思
  • 马思:*思
  • 马列主义:马*义
    public function getMaskName()
    {
        if (mb_strlen($this->name) > 2) {
            return mb_substr_replace($this->name, '*', 1, -1);
        } else {
            return mb_substr_replace($this->name, '*', 0, -1);
        }
    }

手机号星号替换

替换样例:

  • 12345679878:123***878
    public function getMaskMobile()
    {
        return substr_replace($this->mobile, '***', 3, -3);
    }

Mysql 数据库空间优化

查看那张表占用空间大

USE information_schema;

SELECT
TABLE_SCHEMA,
TABLE_NAME,
DATA_LENGTH,
INDEX_LENGTH
FROM
TABLES
GROUP BY
TABLE_SCHEMA
ORDER BY
DATA_LENGTH DESC;

修改表采用压缩

USE mydb;

ALTER TABLE mytable ROW_FORMAT = DYNAMIC;

OPTIMIZE TABLE mytable;

如果没有 DYNAMIC,那么采用 COMPRESSED 也可以

修改表采用 tokudb (需要安装 tokudb 引擎)

ALTER TABLE `mytable`
ENGINE=tokudb;

修改字符集

ALTER TABLE `mytable`
DEFAULT CHARACTER SET=gbk

删除日志文件

第一步:登陆进入mysql,并使用 show binary logs; 查看日志文件。

mysql> show binary logs;

第二步:查看正在使用的日志文件:show master status;

mysql> show master status;
+------------------+-----------+--------------+------------------+-------------------+
| File             | Position  | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+-----------+--------------+------------------+-------------------+
| mysql-bin.000005 | 425994852 |              |                  |                   |
+------------------+-----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

当前正在使用的日志文件是mysql-bin.000005,那么删除日志文件的时候应该排除掉该文件。

mysql> purge binary logs to 'mysql-bin.000005';

删除除mysql-bin.000005以外的日志文件。

mysql 定时清理日志文件

如果每次等到发现空间不足的时候才去手动删除日志文件,这种方式是很不理想的。

那么,我们就需要设置mysql,让它能自动清理日志文件。

编辑mysql的配置文件,设置expire_logs_days(mysql定时删除日志文件)

[root@sam ~]# vim /etc/my.cnf

在my.cnf中,添加或修改expire_logs_days的值 (这里设置的自动删除时间为10天, 默认为0不自动删除)

expire_logs_days=10

修改后,重启mysql就会生效。

但是,在生产环境中,重启mysql数据库往往会付出很高的代价。

于是,可以在不重启mysql的情况下,修改expire_logs_days值

如下:

mysql> show variables like '%log%';
mysql> set global expire_logs_days = 10;

设置完后,可以通过 show variables like '%log%'; 看到expire_logs_days的值已被修改成10。

注意:通过这种方式设置expire_logs_days虽然不需要重启mysql即可生效,但是该方式在重启mysql之后,值会被恢复。

于是,建议通过mysql命令设置expire_logs_days的同时,也修改/etc/my.cnf下的expire_logs_days=10配置,这样在下次重启mysql的时候,expire_logs_days也一样是10;

参考