Schema 与数据类型优化
这是《高性能 MySQL(第三版)》第四章《Schema 与数据类型优化》的读书笔记。
1. 选择优化的数据类型
数据类型的选择原则:
- 越小越好:选择满足需求的最小类型。注意,增大数据类型的范围是耗时操作,尽量避免。
- 简单:整型比字符操作代价更低。
- 尽量避免 NULL 列:列最好指定为 NOT NULL,除非确实可以是 NULL。如果查询中包含可为 NULL 的列,会使索引、索引统计和值比较都更复杂。可为 NULL 的列占用更多存储空间,在 MySQL 里也需要特殊处理。如果可为 NULL 的列被索引,每个索引记录需要一个额外的字节,在 MyISAM 里甚至可能导致固定大小的索引变成可变大小的索引。
把 NULL 列改为 NOT NULL 列带来的性能提升比较小,但是用于索引的列最好是 NOT NULL。另外,InnoDB 使用单独的位(bit)存储 NULL 值,包含很多 NULL 值的稀疏数据的空间效率比较高。
首先选择大类型:数字、字符串、时间、布尔值等。然后选择具体类型。
1.1 整数类型
可用的整型数据有:
- TINYINT:8 bit。
- SMALLINT:16 bit。
- MEDIUMINT:24 bit。
- INT:32 bit。
- BIGINT:64 bit。
所有的整数类型都支持 UNSIGNED 属性,表示无符号数据,例如 TINYINT UNSIGNED。有符号和无符号整型数据存储空间一样,性能一样。
MySQL 中可以为整数类型指定宽度,例如 INT(11)
,这个宽度只是规定了 MySQL 交互工具用来显示字符的个数,不影响存储和计算。
1.2 实数类型
可用的实数数据有:
- 浮点类型:
- FLOAT:32 bit。不精确类型,支持浮点运算。
- DOUBLE:64 bit。不精确类型,支持浮点运算。
- DECIMAL:最多允许 65 个数字,例如
DECIMAL(33,32)
,DECIMAL(65,0)
。可以存储精确的小数,也可以存储比 BIGINT 还大的整数,支持精确计算。因为 CPU 不支持对 DECIMAL 的直接计算,所以 MySQL 服务器自身实现了 DECIMAL 的高精度计算。
MySQL 支持精确类型(DECIMAL),也支持不精确类型(浮点类型,即 FLOAT 和 DOUBLE)。
FLOAT、DOUBLE 和 DECIMAL 类型都可以指定精度。例如 DOUBLE(12,3)
表示最多 9 位整数、3 位小数。DECIMAL(18,9)
表示小数点两边各存储 9 个数字,一共使用 9 个字节(小数点占一个字节)。
DECIMAL 需要的存储空间大,计算开销高,如果数据量很大,可以考虑用 BIGINT 替代 DECIMAL。例如金额需要保证 0.001 的精度,则可以将所有金额乘以 1000 后取整存入 BIGINT 类型的字段,从而避免浮点数计算不准确和 DECIMAL 精确计算代价高的问题。
1.3 字符串类型
MySQL 中每个字符串列可以定义自己的字符集和排列规则(校对规则,collation)。
1.3.1 VARCHAR 和 CHAR 类型
MySQL 中最重要的字符串类型,其在内存和磁盘中的存储方式跟存储引擎相关。这里假设用的是 InnoDB 或 MyISAM 引擎。
- VARCHAR:变长字符串,节省空间(但是如果用 ROW_FORMAT = FIXED 创建表,每行都会定长存储,浪费空间)。需要 1 个或 2 个额外字节记录字符串长度(如果列的最大长度小于等于 255 字节则只需要 1 个字节,否则需要 2 个字节)。例如,对于 latin1 字符集,一个 VARCHAR(10) 的列需要 11 个字节的存储空间,VARCHAR(1000) 的列需要 1002 个字节的存储空间。
在执行 UPDATA 操作时,如果需要增大行的长度,需要额外工作。如果磁盘当前页的空间不够,不同存储引擎的处理方式不同。MyISAM 会将行拆成不同的片段存储,InnoDB 则需要分裂页来使行可以放进页内。InnoDB 会把过长的 VARCHAR 存储为 BLOB。 - CHAR:定长字符串,分配固定空间,如果字符串长度小于存储空间,则剩余空间填充空格。对于单字节字符集,
CHAR(1)
只需要一个字节,而VARCHAR(1)
则需要两个字节(包括记录长度的一个字节)。 - VARBINARY:二进制变长字符串,存储字节码而不是字符。
- BINARY:二进制定长字符串,存储字节码而不是字符,使用
\0
(零字节)填充而不是空格,且检索时不会去掉填充值。
适合使用 VARCHAR 的场景:
- 字符串列的最大长度比平均长度大得多
- 列很少更新,所以碎片不是问题
- 使用 UTF-8 字符集,每个字符用不同的字节数进行存储
适合使用 CHAR 的场景:
- 短字符串
- 定长字符串,例如密码的 HASH 值
- 经常变更的字符串,不易产生碎片
注意:CHAR 类型的字符串在存储时,会自动截断字符串末尾的空格:
MariaDB [foo]> CREATE TABLE char_test(char_col CHAR(10));
Query OK, 0 rows affected (0.04 sec)
MariaDB [foo]> INSERT INTO char_test(char_col) VALUES
-> ('string1'), (' string2'), ('string3 ');
Query OK, 3 rows affected (0.02 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [foo]> SELECT CONCAT("'", char_col, "'") FROM char_test;
+----------------------------+
| CONCAT("'", char_col, "'") |
+----------------------------+
| 'string1' |
| ' string2' |
| 'string3' |
+----------------------------+
3 rows in set (0.00 sec)
VARCHAR 类型的字符串在存储时,则不会截断字符串末尾的空格:
MariaDB [foo]> CREATE TABLE varchar_test(varchar_col VARCHAR(10));
Query OK, 0 rows affected (0.04 sec)
MariaDB [foo]> INSERT INTO varchar_test VALUES
-> ('string1'), (' string2'), ('string3 ');
Query OK, 3 rows affected (0.01 sec)
Records: 3 Duplicates: 0 Warnings: 0
MariaDB [foo]> SELECT CONCAT("'", char_col, "'") FROM varchar_test;
+----------------------------+
| CONCAT("'", char_col, "'") |
+----------------------------+
| 'string1' |
| ' string2' |
| 'string3 ' |
+----------------------------+
3 rows in set (0.00 sec)
1.3.2 BLOB 和 TEXT 类型
BLOB:二进制方式存储大数据的字符串类型,没有字符集和排序规则。具体的类型有:TINYBLOB, SMALLBLOB, BLOB, MIDIUMBLOB, LONGBLOB
TEXT:字符方式存储大数据的字符串类型,有字符集和排序规则。具体的类型有:TINYTEXT, SMALLTEXT, TEXT, MIDIUMTEXT, LONGTEXT
在 MySQL 中,每个 BLOB 和 TEXT 类型的值都是独立对象。当值太大时,InnoDB 还会使用专门的外部存储区域来存储,此时行内只需 1-4 个字节存储指针。
1.3.3 ENUM 枚举类型代替字符串
使用枚举类型可以节省存储空间。MySQL 内部将每个枚举类型的字段存储为整数,并在表的 .frm
文件中保存“数字-字符串”映射关系的“查找表”。
MariaDB [foo]> CREATE TABLE enum_test( e ENUM('dog', 'fish', 'apple') NOT NULL);
Query OK, 0 rows affected (0.17 sec)
MariaDB [foo]> desc enum_test;
+-------+----------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+----------------------------+------+-----+---------+-------+
| e | enum('dog','fish','apple') | NO | | NULL | |
+-------+----------------------------+------+-----+---------+-------+
1 row in set (0.01 sec)
MariaDB [foo]> INSERT INTO enum_test(e) VALUES('fish'), ('dog'), ('apple');
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
MySQL 的枚举字段存储的实际上是数字而不是字符串:
MariaDB [foo]> SELECT e + 0 FROM enum_test; <-------实际存储整数值
+-------+
| e + 0 |
+-------+
| 2 |
| 1 |
| 3 |
+-------+
3 rows in set (0.00 sec)
MariaDB [foo]> SELECT e FROM enum_test; <-------取数据时自动转为字符串
+-------+
| e |
+-------+
| fish |
| dog |
| apple |
+-------+
3 rows in set (0.00 sec)
枚举字段排序时,默认按照内部存储的整数进行排序。可以使用 FIELD()
函数显式指定排序顺序,但会导致 MySQL 无法利用索引消除排序:
MariaDB [foo]> SELECT e FROM enum_test ORDER BY e; <-------排序时,根据实际存储的整数值排序
+-------+
| e |
+-------+
| dog |
| fish |
| apple |
+-------+
6 rows in set (0.06 sec)
MariaDB [foo]> SELECT e FROM enum_test ORDER BY FIELD(e, 'apple', 'dog', 'fish'); <-------自己制定排序方式
+-------+
| e |
+-------+
| apple |
| dog |
| fish |
+-------+
6 rows in set (0.00 sec)
枚举字段如果需要增删可用的枚举值,则需要使用 ALTER TABLE。如果枚举类型添加字符串,MySQL 会自动修改字段中保存的整数值以匹配字符串。为了不重建整个表,最好在列表末尾新增加字符串:
MariaDB [foo]> ALTER TABLE enum_test MODIFY e ENUM('dog', 'fish', 'apple', 'banana');
Query OK, 6 rows affected (0.08 sec)
Records: 6 Duplicates: 0 Warnings: 0
MariaDB [foo]> DESC enum_test;
+-------+-------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------------------------------+------+-----+---------+-------+
| e | enum('dog','fish','apple','banana') | YES | | NULL | |
+-------+-------------------------------------+------+-----+---------+-------+
1 row in set (0.00 sec)
MariaDB [foo]> SELECT e + 0 FROM enum_test; <-------存储的整数值不受影响
+-------+
| e + 0 |
+-------+
| 2 |
| 1 |
| 3 |
+-------+
3 rows in set (0.00 sec)
MariaDB [foo]> ALTER TABLE enum_test MODIFY e ENUM('test', 'dog', 'fish', 'apple', 'banana');
Query OK, 6 rows affected (0.04 sec)
Records: 6 Duplicates: 0 Warnings: 0
MariaDB [foo]> SELECT e + 0 FROM enum_test; <-------存储的整数值受影响
+-------+
| e + 0 |
+-------+
| 3 |
| 2 |
| 4 |
+-------+
6 rows in set (0.00 sec)
MariaDB [foo]> SELECT e FROM enum_test; <-------实际读出来的字符串不会变化
+-------+
| e |
+-------+
| fish |
| dog |
| apple |
+-------+
6 rows in set (0.00 sec)
1.4 日期和时间类型
- DATETIME:时间范围 1001 - 9999 年,精度范围 1 秒。内部把日期和时间封装到格式为 YYYYMMDDHHMMSS 的整数中,与时区无关,使用 8 个字节的存储空间。MySQL 默认以可排序、无歧义的格式显示 DATETIME 的值,例如 “2018-04-26 16:51:05”。
- TIMESTAMP:时间范围 1970 - 2038 年,保存从 1970 年 1 月 1 日凌时开始的秒数,跟 UNIX 的时间戳一样。只使用 4 个字节的存储空间。
TIMESTAMP 显示的值依赖于时区,操作系统、MySQL 服务器及客户端都有时区设置。例如,存储值为 0 的 TIMESTAMP 在中国(东八区)显示为“1970-01-01 08:00:00”。如果跨时区访问或存储数据,TIMESTAMP 和 DATETIME 的行为完全不一样。 - DATE:占用 4 个字节。表示 年月日 YYYY-MM-DD,范围 1000 - 9999。
- TIME:占用 3 个字节。表示 时分秒 HH:MM:SS。
- YEAR:占用 1 个字节。表示 年 YYYY,范围 1901 - 2155。
TIMESTAMP 的规则相当复杂,且在不同版本的 MySQL 中会发生变化。如果需要跨时区的人使用,最好使用 TIMESTAMP。常见的特殊属性有:
- 创建表时,所有的 TIMESTAMP 字段默认为 NOT NULL,且第一个 TIMESTAMP 字段有默认值 CURRENT_TIMESTAMP。
- INSERT 插入数据时,如果没有指定第一个 TIMESTAMP 列的值,MySQL 会设置这个列的值为当前时间。
- UPDATE 更新数据时,MySQL 会默认更新第一个 TIMESTAMP 列的值为当前时间(除非明确指定值)。
MySQL 内置函数可以实现时间戳和日期的互相转换:
- FROM_UNIXTIME():将 UNIX 时间戳转为日期。
- UNIX_TIMESTAMP():将日期转为 UNIX 时间戳。
MariaDB [foo]> CREATE TABLE t_test (id INT, t1 TIMESTAMP, t2 TIMESTAMP, d1 DATETIME, d2 DATETIME);
Query OK, 0 rows affected (0.13 sec)
MariaDB [foo]> DESC t_test;
+-------+-----------+------+-----+---------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+---------------------+-----------------------------+
| id | int(11) | YES | | NULL | |
| t1 | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | <------第一个 TIMESTAMP 字段会默认填充当前时间,且在更新数据时同步刷新
| t2 | timestamp | NO | | 0000-00-00 00:00:00 | | <------第二个 TIMESTAMP 字段会默认填充 0000-00-00 00:00:00
| d1 | datetime | YES | | NULL | |
| d2 | datetime | YES | | NULL | |
+-------+-----------+------+-----+---------------------+-----------------------------+
5 rows in set (0.01 sec)
MariaDB [foo]> CREATE TABLE time_test (id INT, stamp TIMESTAMP, time DATETIME);
Query OK, 0 rows affected (0.18 sec)
MariaDB [foo]> desc time_test;
+-------+-----------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-----------+------+-----+-------------------+-----------------------------+
| id | int(11) | YES | | NULL | |
| stamp | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| time | datetime | YES | | NULL | |
+-------+-----------+------+-----+-------------------+-----------------------------+
3 rows in set (0.02 sec)
MariaDB [foo]> INSERT INTO time_test VALUES(1, null, '2018-04-27 09:27:00');
Query OK, 1 row affected (0.00 sec)
MariaDB [foo]> SELECT * FROM time_test;
+------+---------------------+---------------------+
| id | stamp | time |
+------+---------------------+---------------------+
| 1 | 2018-04-27 09:28:25 | 2018-04-27 09:27:00 | <------插入时,TIMESTAMP 会默认填充当前时间
+------+---------------------+---------------------+
1 row in set (0.00 sec)
MariaDB [foo]> SELECT stamp + 0 FROM time_test;
+----------------+
| stamp + 0 |
+----------------+
| 20180427092825 |
+----------------+
1 row in set (0.00 sec)
MariaDB [foo]> SELECT time + 0 FROM time_test;
+----------------+
| time + 0 |
+----------------+
| 20180427092700 |
+----------------+
1 row in set (0.00 sec)
MariaDB [foo]> UPDATE time_test SET id = 2 WHERE id = 1;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
MariaDB [foo]> SELECT * FROM time_test;
+------+---------------------+---------------------+
| id | stamp | time |
+------+---------------------+---------------------+
| 2 | 2018-04-27 09:30:02 | 2018-04-27 09:27:00 | <------更新时,TIMESTAMP 会默认更新为当前时间
+------+---------------------+---------------------+
1 row in set (0.00 sec)
1.5 位数据类型
MySQL 中的位类型从技术上看都是字符串类型。
1.5.1 BIT(不建议用)
BIT 列中可以存储一个或多个 true/false 值。BIT(n)
定义了存储 n 个位的字段,BIT 列最大支持 64 个位。
BIT 的行为因存储引擎的不同而不同。MyISAM 会打包存储所有的 BIT 列,17 个单独的 BIT 列只需要 17 个位存储(假设没有可为 NULL 的列),只需要 3 个字节。假设存储引擎是 Memory 或 InnoDB,每个 BIT 列使用一个足够存储的最小整数来存放,无法节省存储空间。
MySQL 把 BIT 当做字符串类型,而不是数字类型。当检索 BIT(1)
的值时,结果是一个包含二进制 0 或 1 的字符串,而不是 ASCII 码的 0 或 1。但是在数字上下文的场景中,会自动将位字符转为对应的 ASCII 码。例如,对于存储了 b'00111001'
的 BIT(8) 列,正常检索时得到字符码为 57 的字符‘9’,但是在数字上下文场景中,得到数字 57:
MariaDB [foo]> CREATE TABLE bit_test(a BIT(8));
Query OK, 0 rows affected (0.01 sec)
MariaDB [foo]> INSERT INTO bit_test VALUES(b'00111001');
Query OK, 1 row affected (0.02 sec)
MariaDB [foo]> SELECT a, a + 0 FROM bit_test;
+------+-------+
| a | a + 0 |
+------+-------+
| 9 | 57 |
+------+-------+
1 row in set (0.00 sec)
1.5.2 SET
如果需要保存很多 true/false 值,可以合并这些列到一个 SET 数据类型,在 MySQL 内部以一系列打包的位的集合来表示。存储空间利用率高,使用方便(可以在查询中使用 FIELD()
和 FIELD()
函数)。缺点是改变列的定义时,代价较高(需要使用 ALTER TABLE),对于大表很麻烦。
1.6 选择标识符
标识列(identifier column)选择合适的数据类型很重要。标识列可以与其他值进行比较,或通过标识列寻找其他列。标识列也可以作为其他表中的外键。
选择标识列的类型时,既要考虑存储类型,也要考虑 MySQL 对这种类型怎么执行计算和比较。例如 MySQL 内部用整数存储 ENUM 和 SET 类型,在比较操作时转为字符串。
整数类型
整数是标识列最佳选择,快,且可以使用 AUTO_INCREMENT。
ENUM 和 SET 类型
标识列的糟糕选择。ENUM 和 SET 列适合存储固定信息,例如性别、产品类型。
字符串类型
尽量避免,慢,存储空间大。尤其是 MyISAM,会对字符串压缩索引。
1.7 特殊类型数据
例如低于秒级精度的时间戳。对于 IPv4 地址,可以使用无符号整数存储,MySQL 提供了 INET_ATON() 和 INET_NTOA() 函数进行转换。
2. MySQL schema 设计中的陷阱
太多列
MySQL 的存储引擎 API 工作时需要在服务器层和存储引擎层之间通过行缓冲格式拷贝数据,然后在服务器层将缓冲内容解码成各个列。MyISAM 的变长行和 InnoDB 的行结构都需要转换。
太多关联
单个查询最多在 12 个表内做关联。
全能的枚举
变相的枚举
NULL
3. 范式和反范式
范式化数据库中,每个事实数据会出现且只出现一次。反范式化数据库中,信息是冗余的,可能存储在多处。
范式化的优点:
- 更新操作快
- 较好的范式化可以减少数据冗余,修改简单
- 范式化好的表更新
- 冗余少的数据可以更少的使用 DISTINCT 或 GROUP BY 语句
范式化设计的 schema 的缺点是通常需要关联查询。
反范式化的优点:所有数据都在一张表中,避免了关联。
最常见的混用范式化和反范式化的例子是复制或缓存,在不同的表中存储相同的特定列。可以通过触发器更新冗余列。
4. 缓存表和汇总表
完全独立的缓存表和汇总表,可以存储少量冗余数据。
缓存表是实时维护的。
汇总表是定期重建的。
可以使用物化视图(MySQL 需要借助工具 Flexviews)和计数器表。
5. 加快 ALTER TABLE 操作的速度
MySQL 执行 ALTER TABLE 时,通常是用新的结构创建一个空表,从旧表中查出所有数据插入新表,再删除旧表。
大部分 ALTER TABLE 操作会中断 MySQL 服务。有几种方式可以避免停机:
- 主备结构时,可以在不提供服务的备用库执行操作,完成后再主备切换。
- 影子拷贝:用新的表结构创建新表,然后通过重命名和删表操作交换两张表。可以使用 Facebook 的“online schema change”工具。
改变或删除列的默认值时,可以使用 ALTER COLUMN(不一定重建表)或 MODIFY COLUMN(需要重建表)。列的默认值存储在表的 .frm
文件中,
5.1 只修改 .frm 文件
有风险。。。
5.2 快速创建 MyISAM 索引
ALTER TABLE 时,先禁用索引,载入数据后再启用索引,可以高效载入数据。
Schema 与数据类型优化的更多相关文章
- mysql笔记01 MySQL架构与历史、Schema与数据类型优化
MySQL架构与历史 1. MySQL架构推荐参考:http://www.cnblogs.com/baochuan/archive/2012/03/15/2397536.html 2. MySQL会解 ...
- MySQL Schema与数据类型优化
Schema与数据类型优化 选择优化的数据类型 1.更小的通常更好 更小的数据类型通常更快,因为它们占用更少的磁盘,内存和CPU缓存 2.简单就好 简单数据类型的操作通常需要更少的CPU周期.例如:整 ...
- MySQL设计之Schema与数据类型优化
一.数据类型优化 1.更小通常更好 应该尽量使用可以正确存储数据的最小数据类型,更小的数据类型通常更快,因为它们占用更少的磁盘.内存和CPU缓存,并且处理时需要的CPU周期更少,但是要确保没有低估需要 ...
- 高性能MySQL笔记 第4章 Schema与数据类型优化
4.1 选择优化的数据类型 通用原则 更小的通常更好 前提是要确保没有低估需要存储的值范围:因为它占用更少的磁盘.内存.CPU缓存,并且处理时需要的CPU周期也更少. 简单就好 简 ...
- Schema与数据类型优化
良好的逻辑设计和物理设计是高性能的基石,应该根据系统将要执行的查询数据来设计schema,这往往需要权衡各种因素. MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要. 更小的通 ...
- Mysql高性能笔记(一):Schema与数据类型优化
1.数据类型 1.1.几个参考优化原则 a. 更小的通常更好 i.更小的数据类型,占用更少磁盘.内存和CPU缓存,需要的CPU周期更少 ii.如果无法确定哪个数据类型是最好的,就选择不会超过范围的最 ...
- MySQL之Schema与数据类型优化
选择优化的数据类型 MySQL支持的数据类型非常多,选择正确的数据类型对于获得高性能至关重要.不管存储哪种类型的数据,下面几个简单的原则都有助于做出更好的选择: 更小的通常更好一般情况下,应该尽量使用 ...
- (三)Schema与数据类型优化
1.Schema schema,中文叫模式,是数据库的组织和结构 2.选择优化的数据类型 更小的通常更好:尽量使用可以正确存储数据的最小数据类型 简单就好:简单数据类型的操作通常需要更少的cpu周期. ...
- 深入学习MySQL 03 Schema与数据类型优化
Schema是什么鬼 schema就是数据库对象的集合,这个集合包含了各种对象如:表.视图.存储过程.索引等.为了区分不同的集合,就需要给不同的集合起不同的名字,默认情况下一个用户对应一个集合,用户的 ...
随机推荐
- C# TCPListener
1: 有两个地方必须做异常处理,异常类型为IOException 服务器读客户端发来的信息时: LeafTCPClient client = (LeafTCPClient)ar.AsyncState; ...
- HDFS中NameNode发生故障没有备份从SecondNameNode恢复
1.Secondary NameNode目录结构 Secondary NameNode用来监控HDFS状态的辅助后台程序,每隔一段时间获取HDFS元数据的快照. 在/opt/module/hadoop ...
- Appium+Python之生成html测试报告
思考:测试用例执行后,如何生成一个直观漂亮的测试报告呢? 分析:1.unittest单元测试框架本身带有一个textTestRunner类,可以生成txt文本格式的测试报告,但是页面不够直观 2.我们 ...
- PC端实现浏览器点击分享到QQ好友,空间,微信,微博等
网上现在比较流行的是JIaThis,但是测试的时候,不能分享给QQ好友,一直卡在输入验证码,以下代码亲测有效,可直接使用 <%@ page language="java" c ...
- python编程基础之简单购物车
#good文件夹内容[ ['Iphone7', 5800], ['Coffee', 30], ['疙瘩汤', 10], ['Python Book', 99], ['Bike', 199], ['Vi ...
- Anaconda 安装及Python 多版本间切换
安装 Anaconda 安装anaconda 安装较为简单,这里参考官方文档:https://docs.continuum.io/anaconda/install/linux.html 在文件目录下执 ...
- R语言——ifelse函数
在数据处理中,经常会遇到要对判断结果做处理的情况.if函数是经常遇到的. ifelse(cond,statment1,statment2) 如果cond成立,执行statment1,否则执行statm ...
- docker安装各种坑
今天记录一下之前安装docker遇到的各种坑. 我们从http://mirrors.aliyun.com/docker-toolbox/windows/docker-toolbox/这个网站下载. 下 ...
- AIX下的ha高可用集群cluster
安装ha软件 一.安装软件 最稳定的版本是5.4.0,优先安装稳定版本5.4 安装依赖于包base.data, cluster的man包安装失败原因是缺少base.data包 安装所有cluster. ...
- 项目中dubbo的标准配置
# Spring boot applicationspring: application: name: hello-dubbo-service-user-provider # UserService ...