从零入门到实战

知识库
知识库文档
/tech-stacks/mariadb/tutorial/从零入门到实战.md

文档

1. 什么是 MariaDB?

MariaDB 是 MySQL 的完全兼容替代品,由 MySQL 之父 Monty Widenius 在 Oracle 收购 Sun/MySQL 后创建(2009 年),以保障 MySQL 生态的开源自由。

MySQL vs MariaDB

维度 MySQL 8.0 MariaDB 11.x
JSON 支持 JSON 类型 + 函数 相同,还增加了 JSON 校验约束
存储引擎 以 InnoDB 为主 多了 Aria、ColumnStore、MyRocks
窗口函数 支持 支持(10.2+)
CTE/递归 支持 支持
RETURNING 子句 ✅ (10.5+)(省去额外查询)
序列(Sequence) ✅ (10.3+)
系统版本表 ✅ (10.3+)(自动保留历史)
许可 GPL GPL + LGPL(客户端库更宽松)

2. MariaDB 独有特性详解

RETURNING 子句

-- 插入同时返回数据,无需 SELECT
INSERT INTO users (name, email) VALUES ('张三', 'zs@test.com')
RETURNING id, name, created_at;

序列(Sequence)

CREATE SEQUENCE order_seq START WITH 1000 INCREMENT BY 1;
SELECT NEXTVAL(order_seq);  -- 1000

CREATE TABLE orders (
    order_no BIGINT DEFAULT NEXTVAL(order_seq),
    user_id INT,
    amount DECIMAL(10,2)
);

系统版本表(自动记录历史)

CREATE TABLE products (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    price DECIMAL(8,2)
) WITH SYSTEM VERSIONING;

-- 更新后查询历史
SELECT * FROM products FOR SYSTEM_TIME ALL
WHERE id = 1 AND price < 200;

3. 实战:图书管理系统

CREATE DATABASE library CHARACTER SET utf8mb4;
USE library;

-- 读者表
CREATE TABLE readers (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    card_no VARCHAR(20) UNIQUE NOT NULL,
    phone VARCHAR(20),
    registered_at DATE DEFAULT (CURRENT_DATE)
);

-- 图书表(含系统版本追踪)
CREATE TABLE books (
    id INT AUTO_INCREMENT PRIMARY KEY,
    isbn VARCHAR(20) UNIQUE NOT NULL,
    title VARCHAR(200) NOT NULL,
    author VARCHAR(100),
    price DECIMAL(8,2),
    stock INT DEFAULT 0 CHECK(stock >= 0)
) WITH SYSTEM VERSIONING;

-- 借阅记录
CREATE TABLE borrows (
    id INT AUTO_INCREMENT PRIMARY KEY,
    reader_id INT NOT NULL,
    book_id INT NOT NULL,
    borrow_date DATE DEFAULT (CURRENT_DATE),
    return_date DATE,
    FOREIGN KEY (reader_id) REFERENCES readers(id),
    FOREIGN KEY (book_id) REFERENCES books(id)
);

-- 借书(事务)
DELIMITER $$
CREATE PROCEDURE borrow_book(
    IN p_reader_id INT,
    IN p_book_id INT
)
BEGIN
    DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK;

    START TRANSACTION;

    -- 检查库存
    IF (SELECT stock FROM books WHERE id = p_book_id) <= 0 THEN
        SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '库存不足';
    END IF;

    -- 扣减库存
    UPDATE books SET stock = stock - 1 WHERE id = p_book_id;

    -- 创建借阅记录
    INSERT INTO borrows (reader_id, book_id) VALUES (p_reader_id, p_book_id);

    COMMIT;
END$$
DELIMITER ;

-- 调用
INSERT INTO readers (name, card_no) VALUES ('张三', 'R2024001');
INSERT INTO books (isbn, title, author, price, stock) VALUES
    ('978-7-111', '数据库系统概念', 'Silberschatz', 99.00, 3);
CALL borrow_book(1, 1);

4. ColumnStore 列式引擎(分析场景)

-- MariaDB 10.5+ 内置 ColumnStore
CREATE TABLE sales_log (
    id INT AUTO_INCREMENT,
    product_id INT,
    amount DECIMAL(10,2),
    sale_date DATE,
    region VARCHAR(50)
) ENGINE=ColumnStore;

-- 列式存储对聚合查询极快
SELECT region, SUM(amount) AS total
FROM sales_log
WHERE sale_date BETWEEN '2024-01-01' AND '2024-12-31'
GROUP BY region;

5. 优化技巧

-- 慢查询日志
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;

-- 查看执行计划
EXPLAIN FORMAT=JSON
SELECT * FROM borrows WHERE reader_id = 1;

-- 使用 ANALYZE + FORMAT=JSON(MariaDB 独有)
ANALYZE FORMAT=JSON
SELECT b.title, r.name
FROM borrows br
JOIN books b ON br.book_id = b.id
JOIN readers r ON br.reader_id = r.id;

思考题

  1. 系统版本表(SYSTEM VERSIONING)和外键约束能共存吗?为什么?
  2. 什么场景下 ColumnStore 比 InnoDB 更快?反过来呢?
  3. MariaDB 的 RETURNING 子句相比 MySQL 的 LAST_INSERT_ID()SELECT,有什么优势?

推荐工具

  • HeidiSQL(Windows GUI)- 对 MariaDB 完美支持
  • Beekeeper Studio(跨平台)
  • mycli(命令行智能补全):pip install mycli

信息

路径
/tech-stacks/mariadb/tutorial/从零入门到实战.md
更新时间
2026/5/31