MariaDB虚拟列

MariaDB 10.2 版本引入了多项新特性,包括增强的虚拟列功能,支持表达式的 DEFAULT 定义以及外键 CHECK 约束等。这些改进提升了数据库的功能性和灵活性。

继 MariaDB 10.1 之后,对标 MySQL 5.7 的 MariaDB 10.2 版本也即将封板,那么我们就来看看新的版本有哪些新的功能吧。

之前的月报我们写过一篇关于 Window Function 的介绍,除此之外,10.2.2 又即将发布一些新的特性。

Virtual Columns 进一步加强

目前有两种类型的虚拟列:PERSISTENT/STORED 类型,这种类型的虚拟列的值是直接存在表中的;而 VIRTUAL 类型,其实只是一个定义,表结构中并不包括这个列,在需要用到的时候临时计算。默认值是 VIRTUAL。

虚拟列的语法

<type> [GENERATED ALWAYS] AS ( <expression> ) [VIRTUAL | PERSISTENT | STORED] [UNIQUE] [UNIQUE KEY] [COMMENT <text>]

限制
  1. 只有支持的引擎才能使用虚拟列,目前InnoDB, Aria, MyISAM 和 CONNECT 引擎都能支持。
  2. 有限的支持虚拟列索引。VIRTUAL 类型的虚拟列不能作为主键也不能建索引。
  3. PERSISTENT 类型的虚拟列可以建索引,也可以作为外键,但是不支持 ON UPDATE CASCADE, ON UPDATE SET NULL, ON DELETE SET NULL。
  4. 不能用使用自定义函数来定义虚拟列,内置的函数可以。
  5. 不能定义虚拟列的虚拟列。
用例

表结构如下

USE TEST;

CREATE TABLE table1 (
     a INT NOT NULL,
     b VARCHAR(32),
     c INT AS (a mod 10) VIRTUAL,
     d VARCHAR(5) AS (left(b,5)) PERSISTENT);

用 DESCRIBE 语法来看表结构,在 Extra 列能看到相关的信息。

DESCRIBE table1;
+-------+-------------+------+-----+---------+------------+
| Field | Type        | Null | Key | Default | Extra      |
+-------+-------------+------+-----+---------+------------+
| a     | int(11)     | NO   |     | NULL    |            |
| b     | varchar(32) | YES  |     | NULL    |            |
| c     | int(11)     | YES  |     | NULL    | VIRTUAL    |
| d     | varchar(5)  | YES  |     | NULL    | PERSISTENT |
+-------+-------------+------+-----+---------+------------+

再来做一些操作看效果

INSERT INTO table1 VALUES (1, 'some text',default,default);
Query OK, 1 row affected (0.00 sec)

INSERT INTO table1 VALUES (2, 'more text',5,default);
Query OK, 1 row affected, 1 warning (0.00 sec)

Warning (Code 1645): The value specified for computed column 'c' in table 'table1' ignored.

INSERT INTO table1 VALUES (123, 'even more text',default,'something');
Query OK, 1 row affected, 2 warnings (0.00 sec)

Warning (Code 1645): The value specified for computed column 'd' in table 'table1' ignored.
Warning (Code 1265): Data truncated for column 'd' at row 1

SELECT * FROM table1;
+-----+----------------+------+-------+
| a   | b              | c    | d     |
+-----+----------------+------+-------+
|   1 | some text      |    1 | some  |
|   2 | more text      |    2 | more  |
| 123 | even more text |    3 | even  |
+-----+----------------+------+-------+
3 rows in set (0.00 sec)

可以看到虚拟列都起效果了。

DEFAULT 支持表达式

在当前的所有MySQL版本及分支中,都只能定义固定的 DEFAULT 值,或者特定的类型如 AUTO_INCREMENT, CURRENT_TIMESTAMP。
在 10.1 中能支持 DATETIME 类型也使用 CURRENT_TIMESTAMP 定义默认值。
然而 MariaDB 10.2 中已经可以使用表达式来定义固定值。

例如你可以这么定义:

CREATE TABLE t1 (a int DEFAULT (1+1), b int DEFAULT (a+1));
CREATE TABLE t2 (a bigint primary key DEFAULT UUID_SHORT());

但是表达式不支持存储函数和子查询,而且表达式中如果包含另外的列,那么那个列必须在当前列之前定义了。

并且 BLOB 和 TEXT 类型也支持DEFAULT值定义了。

但是必须注意,在 DEFAULT 使用表达式,必须使用ROW格式才能保证复制的数据安全,当然,任何时候我们都建议使用ROW_FORMAT。

外键定义支持表达式CHECK

CHECK的语法

InnoDB是支持外键约束的,基本语法如下:

[CONSTRAINT [symbol]] FOREIGN KEY
    [index_name] (index_col_name, ...)
    REFERENCES tbl_name (index_col_name,...)
    [ON DELETE reference_option]
    [ON UPDATE reference_option]

reference_option:
    RESTRICT | CASCADE | SET NULL | NO ACTION

可以看到只能支持基本的索引列约束,相对来说是比较简单的。
MariaDB 10.2 将其扩充增加了 CHECK 语法,可以使用表达式来做约束:

CHECK(expression) # 用于检查列的值,在列定义的时候使用
CONSTRAINT [constraint_name] CHECK (expression)
用例

比如我们可以定义一张这样的表。

CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));

比如做一些最简单的数值检查

CREATE TABLE t1 (a INT CHECK (a>2), b INT CHECK (b>2), CONSTRAINT a_greater CHECK (a>b));

INSERT INTO t1(a) VALUES (1);
ERROR 4022 (23000): CONSTRAINT `a` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (3,4);
ERROR 4022 (23000): CONSTRAINT `a_greater` failed for `test`.`t1`

INSERT INTO t1(a,b) VALUES (4,3);
Query OK, 1 row affected (0.04 sec)

可以看到 CHECK 检查的条件生效了。

当然更复杂一点还能引入一些内置函数,包括UDF来做检查:

CREATE TABLE t2 (name VARCHAR(30) CHECK (CHAR_LENGTH(name)>2), start_date DATE, 
  end_date DATE CHECK (start_date IS NULL OR end_date IS NULL OR start_date<end_date));

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2003-12-15', '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Io', '2003-12-15', '2014-11-09');
ERROR 4022 (23000): CONSTRAINT `name` failed for `test`.`t2`

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', NULL, '2014-11-09');
Query OK, 1 row affected (0.04 sec)

INSERT INTO t2(name, start_date, end_date) VALUES('Ione', '2015-12-15', '2014-11-09');
ERROR 4022 (23000): CONSTRAINT `end_date` failed for `test`.`t2`

这样在某些情况下可以把一些简单的逻辑检查放到数据库做,大大简化程序的设计。

总结

MariaDB 10.2 是 MariaDB 一个较大的里程碑版本,很多社区呼声很大的功能都被扩充进去,对用户来说是个福音。MariaDB和MySQL相互竞争,对整个MySQL及其兼容分支的发展都是一个很好的现象,有竞争就有动力,无论是MySQL还是MariaDB,在强大的竞争压力下,进度都快起来了,新功能不断的加入,代码不断的优化,最终受益的都是我们这些用户。

 

转载于:https://my.oschina.net/u/2607135/blog/1923895

<think>好的,我现在需要解释MariaDB是什么。用户之前问过关于安装MySQL的问题,现在转而询问MariaDB,可能是因为之前的回答提到了MariaDB作为替代方案,用户想进一步了解。 首先,我应该从MariaDB的定义开始,说明它是MySQL的一个分支。需要强调它由原MySQL开发者创建,这样用户能理解两者的联系。接着,说明开发背景,比如MySQL被Oracle收购后的担忧,这样用户能明白为何MariaDB会出现。 然后,要比较MariaDB和MySQL的兼容性,指出大多数情况下兼容,但高版本可能有差异。这样用户知道迁移的可能影响。提到性能改进和新特性,比如存储引擎和扩展功能,可以展示MariaDB的优势。 还需要提到主要特点,比如开源协议、社区驱动、支持多种存储引擎等。这些信息帮助用户了解其优势。应用场景部分,区分普通Web应用和需要新特性的情况,帮助用户决定何时选择MariaDB。 最后,安装和使用部分要简明,结合用户之前的命令,给出安装步骤,确保用户能实际操作。可能还需要说明如何切换到MariaDB,特别是如果他们之前安装了MySQL,需要注意冲突和迁移步骤。 需要确保语言口语化,避免技术术语过多,结构清晰。检查是否有遗漏点,比如许可证差异或具体性能优化的例子,是否需要详细展开。可能用户关心兼容性程度,是否需要举例说明不兼容的情况,比如某些特定的MySQL功能在MariaDB中的变化。 总结下来,结构应该是:定义、背景、与MySQL的关系、特点、适用场景、安装使用。这样用户能全面了解MariaDB是什么,为何选择它,以及如何开始使用。</think>MariaDB 是一个**开源关系型数据库管理系统**,可简单理解为 **MySQL 的增强版分支**。以下是关键信息整理: --- ### **1. 起源背景** - **诞生原因**:MySQL 被 Oracle 收购后,原开发团队担心其开源持续性,于 2009 年创建了 MariaDB - **核心目标**:保持与 MySQL 的兼容性,同时提供更开放、高性能的替代方案 --- ### **2. 核心特点** | 特性 | 说明 | |---------------------|----------------------------------------------------------------------| | **完全开源** | 使用 GPL/LGPL 许可证,无商业限制 | | **兼容性** | 支持 MySQL 的协议、接口和命令,可直接替换 | | **性能优化** | 改进查询优化器,支持并行复制、线程池等 | | **存储引擎** | 默认使用 `Aria`(替代 MyISAM),同时包含 `InnoDB`、`RocksDB` 等 | | **扩展功能** | 新增动态虚拟、GIS 扩展等高级功能 | --- ### **3. 与 MySQL 的关键差异** | 对比项 | MariaDB | MySQL | |-----------------|------------------------------|------------------------------| | 开发团队 | 开源社区主导 | Oracle 公司主导 | | 版本兼容 | 支持 MySQL 5.x 兼容,**10.x 版本后差异增大** | 后续版本功能逐渐闭源化 | | 新特性迭代 | 更激进(如支持 `WITH` 语句、`JSON` 增强) | 较保守 | | 默认配置 | 更注重性能优化 | 偏重稳定性 | --- ### **4. 应用场景** - ✅ **推荐使用**: - 需要免费开源且长期维护的数据库 - 原有 MySQL 项目迁移(低版本可平滑过渡) - 需要 `GIS` 地理信息处理或特定扩展功能 - ⚠️ **谨慎选择**: - 依赖 MySQL 8.0+ 独有功能(如 `Invisible Indexes`) - 企业需 Oracle 官方商业支持的情况 --- ### **5. 安装与使用(以 CentOS 为例)** ```bash # 安装 MariaDB 服务端 sudo yum install mariadb-server # 启动服务并设置开机自启 sudo systemctl enable --now mariadb # 安全初始化(设置 root 密码等) sudo mysql_secure_installation # 连接数据库 mysql -u root -p ``` --- ### **6. 如何选择?** - **普通 Web 应用**:优先选 MariaDB(性能更好、社区活跃) - **依赖 MySQL 新特性**:需评估兼容性(可通过 [官方兼容手册](https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/) 核对) - **企业级需求**:考虑 MariaDB 的商业支持版或 MySQL 企业版 --- 📌 **总结**:MariaDB 继承了 MySQL 的核心优势,并持续在开源生态中创新,目前已成为 **Linux 发行版(如 CentOS、Ubuntu)的默认数据库**。除非有强制的 MySQL 依赖,否则建议优先选择 MariaDB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值