likes
comments
collection
share

H2数据库详解

作者站长头像
站长
· 阅读数 4

介绍

H2数据库是一个开源的关系型数据库管理系统(RDBMS),它完全用Java编写,这使得H2可以在任何支持Java的平台上运行,且不受平台限制。H2数据库以其轻量级、高性能和灵活性著称,尤其适用于嵌入式环境和小型应用程序,同时也适合于单元测试和开发阶段。

主要特点和功能

  1. 嵌入式与服务器模式:H2既可以直接嵌入到Java应用程序中,也可以作为独立的数据库服务器运行,提供多用户同时访问的能力。

  2. 多种运行模式

    • 嵌入式内存模式:数据仅保存在内存中,重启后数据丢失,适用于不需要持久化的场景,如缓存或临时数据存储。

    • 嵌入式文件模式:数据库存储在本地文件系统中,适合单进程内的数据存储。 H2数据库详解

    • 服务器模式:运行独立的数据库服务器进程,允许远程客户端通过TCP/IP连接访问数据库。 H2数据库详解

    • 混合模式:混合模式是嵌入式模式和服务器模式的组合。 连接到数据库的第一个应用程序在嵌入模式下执行此操作,但也启动 一个服务器,以便其他应用程序(在不同的进程或虚拟机中运行)可以 并发访问相同的数据。 H2数据库详解

  3. 兼容性与API支持:H2支持标准的SQL语法和JDBC API,还可以通过模拟模式兼容PostgreSQL的ODBC驱动程序。

  4. 事务处理与并发控制:H2提供了事务支持,包括ACID属性,表级锁定机制以及对两阶段提交的支持。

  5. 安全性:支持AES加密数据库文件、SHA-256密码加密以及SSL加密通信,确保数据的安全传输和存储。

  6. 性能优化:采用基于成本的优化器来提高查询性能,部分复杂查询利用遗传算法进行优化。

  7. 轻量级Web控制台:H2包含一个内置的Web控制台工具,可通过浏览器界面管理和监控数据库。

  8. 应用场景

    • 应用程序内嵌数据存储。
    • 快速单元测试。
    • 作为NoSQL缓存,存储关系型且不经常改变的数据。
    • 开发和原型设计阶段的临时数据库替代品。
  9. 附加特性:支持只读数据库、临时表、可滚动和可更新的结果集、大结果集处理、外部结果排序等高级数据库功能。

数据类型

H2数据库支持一系列广泛的数据类型,以下是H2数据库实际支持的数据类型概览:

  • CHARCHARACTER(n):定长字符类型,最大长度由n指定。允许的长度为 1 到 1,000,000,000 个字符。如果未指定长度,则默认使用 1 个字符。使用此数据类型时,整个文本将保留在内存中。太短的字符串会用空格字符右填充。太长的字符串会被规范截断,并被列赋值拒绝。 示例:

    CHARACTER
    CHAR(10)
    
  • VARCHARVARCHAR(n)CHARACTER VARYING(n):变长字符类型,最大长度由n指定。允许的长度为 1 到 1,000,000,000 个字符。长度是大小限制;仅保留实际数据。长度(如果有)应以字符形式指定,单位在 H2 中没有影响。 示例:

    BINARY VARYING(100)
    VARBINARY(1000)
    
  • CLOBTEXTLONGVARCHAR:用于存储大型文本数据,相当于CHARACTER LARGE OBJECT。 示例:

    CHARACTER LARGE OBJECT
    CLOB(10K)
    
  • VARCHAR_IGNORECASE:大小写不敏感的变长字符串类型。

  • BINARYBINARY(n):定长二进制数据类型。

  • VARBINARYVARBINARY(n)BINARY VARYING(n):变长二进制数据类型。

  • BLOBLONGVARBINARY:用于存储大型二进制数据,相当于BINARY LARGE OBJECT

  • BOOLEAN:布尔类型,存储真/假值。

  • TINYINT:小整数类型,通常用于存储1字节的整数值。

  • SMALLINT:较小的整数类型。

  • INTEGERINT: 普通整数类型。

  • BIGINT:用于存储大整数的类型。

  • NUMERIC(p, s)DECIMAL(p, s):固定精度数字类型,p表示总位数,s表示小数点后的位数。

  • REAL:近似浮点数类型,大致对应于Java的float

  • DOUBLEDOUBLE PRECISION:双精度浮点数类型,对应于Java的double

  • DATE:日期类型,存储年、月、日信息。

  • TIME:时间类型,存储小时、分钟、秒信息。

  • TIME WITH TIMEZONE:带时区的时间类型。

  • TIMESTAMP:时间戳类型,存储日期和时间信息。

  • TIMESTAMP WITH TIMEZONE:带时区的时间戳类型。

  • INTERVAL:时间间隔类型,用于存储两个日期或时间之间的差值。

  • JAVA_OBJECT:存储Java对象的类型,但是由于安全性和移植性问题,在现代应用中较少使用。

  • ENUM:枚举类型,存储预定义的一组字符串值。

  • H2还支持地理空间数据类型,但不是以GEOMETRY的形式,而是提供了POINT, LINESTRING, POLYGON, 和其他更具体的几何类型。

  • JSON类型:用于存储JSON格式的数据。

  • UUID:全局唯一标识符类型。

  • ARRAY:数组类型,用于存储相同类型元素的集合。

  • ROW:复合类型,用于定义并存储一组不同类型的字段构成的结构化数据。

数据库文件布局

H2数据库详解

兼容性

所有数据库引擎的行为都略有不同。在可能的情况下,H2 支持 ANSI SQL 标准, 并尝试与其他数据库兼容。但是,仍然存在一些差异:

在MySQL中,文本列默认不区分大小写,而在H2中,它们区分大小写。然而 H2 还支持不区分大小写的列。

H2数据库支持多种数据库兼容模式,这些兼容模式允许H2模拟其他数据库的行为,使得应用程序在开发和测试阶段可以更容易地迁移到不同的生产环境数据库。以下是H2支持的部分兼容模式:

  1. MySQL模式:通过设置特定的URL参数,H2可以模拟MySQL数据库的行为,从而让使用MySQL语句的应用程序能在H2环境下运行。

    jdbc:h2:~/test;MODE=MySQL
    
  2. PostgreSQL模式:H2能够模拟PostgreSQL的SQL语法和行为特征。

    jdbc:h2:~/test;MODE=PostgreSQL
    
  3. DB2模式、Derby模式、HSQLDB模式、MSSQLServer模式、Oracle模式:H2也提供了对这些数据库产品的部分兼容支持,以便在相应的兼容模式下运行时,能够处理符合这些数据库SQL方言的查询。

例如,要启用某个兼容模式,需要在数据库URL中添加MODE参数,并指定对应的数据库名称。

需要注意的是,虽然H2通过兼容模式尽力模仿其他数据库的行为,但它并不能保证完全重现目标数据库的所有特性,特别是那些特有的功能和高级特性。此外,兼容模式主要用于开发和测试环境中的数据库迁移便利性,生产环境中还是推荐直接使用原生数据库产品以获得最佳性能和全部功能支持。

使用示例

以下是一些在H2数据库中进行基本操作的SQL语句示例:

建表语句示例

-- 创建名为`Employees`的表,包含id、name、email和hire_date字段
CREATE TABLE Employees (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100),
    email VARCHAR(255),
    hire_date DATE
);

插入示例

-- 向`Employees`表中插入一行数据
INSERT INTO Employees (name, email, hire_date)
VALUES ('John Doe', 'john.doe@example.com', '2023-01-01');

-- 或者插入多行数据
INSERT INTO Employees (name, email, hire_date)
VALUES 
('Jane Smith', 'jane.smith@example.com', '2023-02-15'),
('Michael Johnson', 'michael.johnson@example.com', '2023-03-10');

查询示例

-- 查询`Employees`表中的所有记录
SELECT * FROM Employees;

-- 查询名字为'John Doe'的员工信息
SELECT * FROM Employees WHERE name = 'John Doe';

-- 查询所有员工的名字和雇佣日期
SELECT name, hire_date FROM Employees;

更新示例

-- 将邮箱地址更新为新值
UPDATE Employees
SET email = 'john.doe.new@example.com'
WHERE name = 'John Doe';

删除示例

-- 删除名字为'Jane Smith'的员工记录
DELETE FROM Employees WHERE name = 'Jane Smith';

-- 或者清空整个表(谨慎操作!)
TRUNCATE TABLE Employees;