使用数据库
- 关系型数据库一般分为
catalog.schema.table
,catalog 的本质就是数据库(database),包含多个 schema;一个 schema 下可以有多个对象,比如表、存储过程、触发器等。MySQL 没有 schema 的概念,但它的 schema 和 database 是等价的; - 建表时 不应使用 数据库 内置关键字,可能会造成一些隐藏的问题;
- 真正的 ORM 框架更加重视建模的规范,前期的建模一旦做好,在业务开发和后期中将无往不利,所以 ORM 的选择对项目的影响蛮大的(前提是使用关系型数据库存储);
- 根据业务场景合理使用外键可以构建更健壮的系统;
数据库三范式
数据库三范式是关系型数据库设计的基础理论,用来保证数据的完整性和减少数据冗余。三范式层层递进,每个范式都是在前一个范式的基础上进行优化和改进。在实际的数据库设计中,应根据具体的需求和场景选择合适的范式来保证数据的完整性和减少数据冗余。
- 第一范式(1NF):它要求每个属性都必须原子性,也就是不可再分。这个范式的目的是确保数据的完整性,防止数据被不合理地分解
(分到不可再分,一个字段只代表一个含义)。 - 第二范式(2NF):第二范式要求在满足第一范式的前提下,非主键属性必须完全依赖于主键,而不是部分依赖
(按照属性进行归类并拆分表进行关联)。 - 第三范式(3NF):在满足第一、二范式的前提下,非主键属性之间不能存在依赖关系。也就是说,每个属性必须是独立的,不能依赖于其他属性
(高度可维护)。
实现了三范式,基本上就是 一张表维护一种数据,然后使用主键进行关联合并为一个整体。
数据字典/映射的必要性
我们经常有类似这样的场景:有合同信息,合同信息中有合同类型;有车辆信息,车辆信息中有车辆类型;有人员信息,人员信息中有人员类型…
这种情况,我们有几种做法:
- 使用数据库 - 每种类型单独建表,该方案不怎么用(除非是递归的父子关系),并且这种类似的场景有很多的话就要多出许多类型表,徒增复杂度;
- 使用数据库 - 使用数据库字典;
- 后端使用枚举
- 前端定义映射
数据字典的建立一般分为以下几种:
- 一张表,简单的 name、value;
- 一张表,在 name、value 之上添加 type
- 两张表,type、type 说明一张表,name、value、type 一张表(若依开源框架就是使用的这种)
就目前的开发而言,第三种方式更加的常见(主要是 ruoyi 的流行),这样可以适用于不同的场景,并且可以充分的利用数据字典表,对于维护也很友好。当然,也能看出有父子关系的树状结构不适用于该方式,所以那种类型表还是需要单独建立的。
浪子建议简单的类型或分类直接定义枚举即可,ORM 都有对应的转换器可以自动完成实体到数据库的映射。
SQL 优化
JDBC URL 参考
BASH
1# db2 示例:jdbc:db2://localhost:50000/MYDB:user=dbadm;password=dbadm;
2# https://www.ibm.com/support/knowledgecenter/SSEPGG_11.5.0/com.ibm.db2.luw.apdv.java.doc/src/tpc/imjcc_r0052342.html
3jdbc:db2://<serverName>[:<portNumber>]/<databaseName>[:<key1>=<value>;[<key2>=<value2>;]]
4
5# h2 示例:jdbc:h2:tcp://localhost/~/test,jdbc:h2:mem:myDB
6# https://h2database.com/html/features.html#database_url
7jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value…]
8
9# mariadb 示例:jdbc:mariadb://localhost:3306/test
10jdbc:mariadb:[replication:|failover:|sequential:|aurora:]//<hostDescription>[,<hostDescription>…]/[database][?<key1>=<value1>[&<key2>=<value2>]] hostDescription:: <host>[:<portnumber>] or address=(host=<host>)[(port=<portnumber>)][(type=(master|slave))]
11
12# mssql 示例:jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks
13# https://docs.microsoft.com/en-us/sql/connect/jdbc/connecting-to-sql-server-with-the-jdbc-driver?view=sql-server-2017
14jdbc:sqlserver://[serverName[\instanceName][:portNumber]][;property=value[;property=value]]
15
16# oracle 示例:jdbc:oracle:thin:@localhost:1521/ORCL_SVC
17# https://docs.oracle.com/en/database/oracle/oracle-database/21/jjdbc/data-sources-and-URLs.html#GUID-AEA8E228-1B21-4111-AF4C-B1F33744CA08
18jdbc:oracle:driver_type:@database_specifier
19
20# pg 示例:jdbc:postgresql://localhost:5432/test
21# https://jdbc.postgresql.org/documentation/head/connect.html
22jdbc:postgresql:[//][host][:port][/database][?key=value…]
SQL
Oracle
SQL
1-- 补全一年 12 个月
2select lpad(level,2,0) from dual connect by level<13
3
4select to_char(sysdate, 'yyyy-') || lpad(level, 2, 0) datevalue from dual connect by level < 13;
5
6--oracle 未来12个月
7SELECT TO_CHAR(ADD_MONTHS(ADD_MONTHS(SYSDATE, 0), ROWNUM - 1), 'YYYY-MM') AS YEARMONTH
8FROM ALL_OBJECTS
9WHERE ROWNUM <= 12;
10
11--oracle 前12个月
12SELECT TO_CHAR(ADD_MONTHS(SYSDATE, 1 - ROWNUM), 'YYYY-MM') AS YEARMONTH
13FROM ALL_OBJECTS
14WHERE ROWNUM <= 12;
评论