MySQL_4 常见函数汇总及演示

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL 第四节 常见函数的汇总和演示 内容分享。

目录

一、统计函数

       1.基本语法 :

       2.代码演示 :  

               演示Ⅰ——

               演示Ⅱ——

二、合计函数

       1.基本语法 :

       2.代码演示 :

三、平均函数

       1.基本语法 :

       2.代码演示 :

四、最值函数

       1.基本语法 :

       2.代码演示 :

五、字符串函数

       1.常用字符串函数 :

       2.代码演示 :

六、数学函数

       1.常用数学函数 :

       2.代码演示 :

七、日期函数

       1.常用日期函数 :

       2.代码演示 :  

八、加密函数

       1.基本语法 :

       2.代码演示 :

九、 流程控制函数

       1.基本语法 :

       2.代码演示 :


一、统计函数

       1.基本语法 :

       SELECT COUNT(*) / COUNT (column_name)... FROM table_name

               [WHERE where_definitition];

       注意事项——

       COUNT(*)表示查询整条记录,只要该记录满足WHERE子句的条件就会被统计在内;

       COUNT(column_name)表示在符合WHERE子句条件的基础上,还必须满足指定列不为NULL

       可以在一条查询语句中使用多个COUNT(column_name),以同时统计多个列,分别显示各个列的统计结果。

       若想查询某列为空的记录,可以配合IF语句来使用,eg : SELECT COUNT(IF(`ebonus` IS NULL, 1, NULL)) FROM `employee`; 该查询语句的意思是如果某条记录的`ebonus`字段为NULL,就返回一个非空字符(这里的1可以是任意的非空字符),继而被COUNT函数统计在内;如果某条记录的`ebonus`字段非NULL,就返回NULL,继而不被COUNT寒素统计在内。
           PS : 亦可以使用两个COUNT函数进行相减的操作,即用统计所有结果的COUNT函数 - 统计非空的COUNT函数。eg :
SELECT COUNT(*) - COUNT(`ebonus`) FROM `employee`; [体现了SQL的灵活性!]

       若希望COUNT函数的统计结果去重,可以在column_name前增加DISTINCT进行修饰,即COUNT(DISTINCT column_name)。

       2.代码演示 :

               演示Ⅰ——

               现有学生表stus如下——

image.png

image.gif编辑

               现要求——

               ①统计表中一共有几位学生(即表中一共有多少条记录);

               ②统计数学成绩大于等于130的学生个数;

              代码如下 :

# 统计stus表中共有多少学生
SELECTCOUNT(*)FROM `stus`;# 统计Math >=130的学生个数
SELECTCOUNT(*)FROM `stus`
WHERE `Math` >=130;

image.gif

              运行结果 :


image.gif

image.png

image.gif

               演示Ⅱ——

               向表中添加两条id = NULL的记录,stus表如下图所示 :

image.png

image.gif编辑

               现要求——

               ①统计英语成绩在80分以下的学生个数;

               ②统计英语成绩在80分以下的,且id不等于NULL的学生个数;

              代码如下 :

# 统计英语成绩在80分以下的学生的个数
SELECTCOUNT(*)FROM `stus`
WHERE `English` <80;# 统计英语成绩在80分以下的并且id不为空的学生的个数
SELECTCOUNT(id)FROM `stus`
WHERE `English` <80;

image.gif

              运行结果 :

image.png

image.gif编辑

image.png

image.gif编辑


二、合计函数

       1.基本语法 :

       SELECT SUM(column_name), SUM(column_name)... FROM table_name

               [WHERE where_definition];

       注意事项——

       SUM函数仅对数值型字段起作用,否则无意义

       可以同时对多列求和。

       2.代码演示 :

               仍对stus表进行操作,stus表目前如下 :

image.png

image.gif编辑

               现要求——

               ①统计所有学生的数学成绩;

               ②统计所有学生的英语成绩;

              代码如下 :

SELECT SUM(`Math`)AS `Math_total`,SUM(`English`)AS `English_total`
FROM `stus`;

image.gif

               运行结果 :

image.png

image.gif编辑


三、平均函数

       1.基本语法 :

       SELECT AVG(column_name), AVG(column_name)... FROM table_name

               [WHERE where_definition];

       注意事项——

       若求平均值的列中有NULL数据,AVG函数会自动跳过该NULL数据
       
除了AVG函数,还可以使用SUM(column_name) / COUNT(column_name)的方式来统计某一字段的平均值。

       2.代码演示 :

               仍对stus表进行操作,stus表目前如下 :

image.png

image.gif编辑

               现要求——

               ①查询所有学生的数学成绩的平均分以及英语成绩的平均分;

               ②将id = 2的学生Ice的数学成绩置为空,再次查询全体学生的数学平均分;

              代码如下 :

SELECT AVG(`Math`), AVG(`English`)FROM `stus`;UPDATE `sts`Math` =NULLWHERE `id` =2;SELECT SUM(`Math`)/COUNT(`Math`)AS `average_Math` FROM `stus`;

image.gif

              运行结果 :

image.png

image.gif编辑

image.png

image.gif编辑


四、最值函数

       1.基本语法 :

       SELECT MAX(columun_name)... / MIN(column_name)... FROM table_name

               [WHERE where_definition];

       注意事项——

       与上面几个函数类似地,MAX和MIN函数也可以多个使用,并且可以混用

       2.代码演示 :

               仍然操作stus表,目前stus表如下 :

image.png

image.gif编辑

               现要求——

               ①查询全体学生中最高的数学成绩和最低的数学成绩;

               ②查询全体学生中最高的英语成绩和最低的英语成绩;

               代码如下 :

SELECT MAX(`Math`), MIN(`Math`)FROM `stus`;SELECT MAX(`English`), MIN(`English`)FROM `stus`;

image.gif

               运行结果 :

image.png

image.gif编辑

image.png

image.gif编辑


五、字符串函数

      1.常用字符串函数 :

      CHARSET(str) : 返回字段(具体的字符串)的字符集类型;

       CONCAT(string, string2...) : 连接多个字符串,将多个列拼接成一列;

        INSTR(string, substring) : 返回substring在string中出现的位置,没有则返回0;

      UCASE(string) : 将当前字符串转换成大写;

        LCASE(string) : 将当前字符串转换成小写;

        LEFT(string, length) : 从string的左边起取length个字符;(RIGHT可从右取)

      LENGTH(string) : 获取当前string的长度(字节);

      8° REPLACE(str, old_string, new_string) : 用new_string替换掉str中的old_string);

        STRCMP(string1, string2) : 按照逐个字符比较两字符串大小;

       10° SUBSTRING(str, position [, length]) : 从str的position开始(默认是1),取LENGTH个字符;

      11° LTRIM(string) / RTRIM(string) / TRIM(string) : 去掉前端空格 / 后端空格 / 两端空格。

      2.代码演示 :

               ① CHARSET(str) : 返回字段的字符集类型;

# 查询ename字段和ecareer字段的字符集类型
SELECT CHARSET(`ename`), CHARSET(`ecareer`)FROM `employee`;

image.gif

image.png

image.gif编辑

               ② CONCAT(string, string2...) : 连接多个字符串;

# 查询自定义拼接后的列
SELECT CONCAT(`ename`,' 是在 ', `hiredate`,' 入职的')AS `hiredate_info`
FROM `employee`;

image.gif

image.png

image.gif编辑

               ③ INSTR(string, substring) : 返回substring在string中出现的位置,没有则返回0;

# DUAL 亚元表,是一个系统表,可以作为默认的测试表来使用
SELECT INSTR('I love programming!','ing'),       INSTR('I love programming!','hahah')AS `test`
FROM DUAL;

image.gif

image.png

image.gif编辑

               ④ UCASE(string) : 将当前字符串转换成大写;

SELECT UCASE(`ename`)FROM `employee`;

image.gif

image.png

image.gif编辑

               ⑤ LCASE(string) : 将当前字符串转换成小写;

SELECT LCASE('I_loVe_YOU')AS `test` FROM DUAL;

image.gif

image.png

image.gif编辑

               ⑥ LEFT(string, length) : 从string的左边起取length个字符;

SELECT LEFT(`ename`,3)FROM `employee`;

image.gif

image.png

image.gif编辑

               ⑦ LENGTH(string) : 获取当前string的长度(字节);

SELECT LENGTH('abc'),       LENGTH('哈哈哈'),       LENGTH('...'),       LENGTH('。。。')FROM DUAL;

image.gif

image.png

image.gif编辑

               ⑧ REPLACE(str, old_string, new_string) : 用new_string替换掉str中的old_string)

SELECT REPLACE('I love programming!','love ','relish ')AS `replace_result`
FROM DUAL;

image.gif

image.gif编辑

               ⑨ STRCMP(string1, string2) : 按照逐个字符比较两字符串大小

SELECT STRCMP('abc','abcdefg')AS `t1`,       STRCMP('dsae','dsad')AS `t2`,       STRCMP('hah','hah')AS `t3`
FROM DUAL;

image.gif

image.png

image.gif编辑

               ⑩ SUBSTRING(str, position [, length]) : 从str的position开始(默认是1),取LENGTH个字符;

SELECT SUBSTRING('I love programming forever!',3,4)AS `sub_res`
FROM DUAL;

image.gif

image.png

image.gif编辑

               ⑩① LTRIM(string) / RTRIM(string) / TRIM(string) : 去掉前端空格 / 后端空格 / 两端空格。

SELECT LTRIM('   haha')AS `left_res`,       RTRIM('hah   ')AS `Right_res`,       TRIM('  haah   ')AS `Trim_res`
FROM DUAL;

image.gif

image.png

image.gif编辑


六、数学函数

       1.常用数学函数 :

      ABS(num) : 求绝对值;

       BIN(decimal_number) :  十进制转二进制;

        CEILING(number) : 向上取整;

      FLOOR(number) : 向下取整;

        CONV(number, from_base, to_base) : 进制转换,将number以一个指定的进制转为另一个进制;

        FORMAT(NUMBER, decimal_places) : 保留小数位数(四舍五入);

       HEX(DecimalNumber) : 转十六进制;

      LEAST(number_1 [, number_2...number_n]) : 求最小值;

        MOD(numerator, denominator) : 取余;

       10° RAND([seed]) : 求0~1.0之间的随机数,若想要返回的随机数不变化,可以给出一个seed(种子)。

       2.代码演示 :

               1ABS(num) : 求绝对值;

# DUAL 亚元表,是一个系统表,可以作为默认的测试表来使用
SELECT ABS(0.00)AS `a1`,       ABS(2333)AS `a2`,       ABS(-6.66)AS `a3`,       ABS(-333)AS `a4`
FROM DUAL;

image.gif

image.png

image.gif编辑

               2BIN(decimal_number) :  十进制转二进制;

SELECT BIN(10),       BIN(11),       BIN(12)FROM DUAL;

image.gif

image.png

image.gif编辑

               3° CEILING(number) : 向上取整;

SELECT CEILING(2.2)AS `c1`,       CEILING(0.8)AS `c2`,       CEILING(-0.99)AS `c3`,       CEILING(-1.01)AS `c4`
FROM DUAL;

image.gif

image.png

image.gif编辑

                FLOOR(number) : 向下取整;

SELECT FLOOR(2.2)AS `f1`,       FLOOR(0.8)AS `f2`,       FLOOR(-0.99)AS `f3`,       FLOOR(-1.01)AS `f4`
FROM DUAL;

image.gif

image.png

image.gif编辑

                CONV(number, from_base, to_base) : 进制转换

SELECT CONV(55,10,2)AS `conv_res1`,       CONV(55,8,10)AS `conv_res2`,       CONV(55,16,10)AS `conv_res3`
FROM DUAL;

image.gif

image.png

image.gif编辑

                FORMAT(NUMBER, decimal_places) : 保留小数位数(四舍五入);

SELECT FORMAT(22.222222,2)AS `test1`,       FORMAT(22.22888,2)AS `test2`,       FORMAT(-0.747,2)AS `test3`
FROM DUAL;

image.gif

image.png

image.gif编辑

                HEX(DecimalNumber) : 转十六进制;

SELECT HEX(16),       HEX(65),       HEX(126)FROM DUAL;

image.gif

image.png

image.gif编辑

                LEAST(number_1 [, number_2...number_n]) : 求最小值;

SELECT LEAST(0,-1.08,22,100)AS `least_1`,       LEAST(3,8,3,11)AS `least_2`,       LEAST(1000,233.3)AS `least_3`
FROM DUAL;

image.gif

image.png

image.gif编辑

                MOD(numerator, denominator) : 取余;

SELECT MOD(10,3),       MOD(55,10)FROM DUAL;

image.gif

image.png

image.gif编辑

               10° RAND([seed]) : 求0~1.0之间的随机数

SELECT FORMAT(RAND(),2)AS `random1`,       FORMAT(RAND(),2)AS `random2`,       FORMAT(RAND(5),2)AS `random3`
FROM DUAL;

image.gif

image.png

image.png


七、日期函数

       1.常用日期函数 :

      CURRENT_DATE : 当前日期;

       CURRENT_TIME : 当前时间;

        CURRENT_TIMESTAMP : 当前时间戳;

      DATE(datetime) : 返回当前时间的日期部分;

       //以下四个函数的date类型可以是DATE, DATETIME, TIMESTAMP类型

        DATE_ADD(date, INTERVAL  d_value  d_type) : 在当前日期的基础上加上一段时间或日期;(d_type 可以是YEAR, MINUTE, SECOND, DAY等)

        DATE_SUB(date, INTERVAL  d_value  d_type) : 在当前日期的基础上减去一段时间或日期;(d_type 可以是YEAR, MINUTE, SECOND, DAY等)

       DATEDIFF(date1, date2) : 返回两个日期的时间差,结果是天;

      TIMEDIFF(date1, date2) : 返回两个时间的时间差,结果是时间;

        NOW() : 返回当前时间;

       10° UNIX_TIMESTAMP() : 返回1970-1-1到现在的秒数。

       11° FROM_UNIXTIME() : 返回年月日。实际开发中,可能会使用int类型来保存一个时间戳,然后使用FROM_UNIXTIME()函数进行转换

       2.代码演示 :

               CURRENT_DATE : 当前日期;
               
CURRENT_TIME : 当前时间;
               
CURRENT_TIMESTAMP : 当前时间戳;

SELECT CURRENT_DATE(),       CURRENT_TIME(),       CURRENT_TIMESTAMP()FROM DUAL;

image.gif

image.png

image.gif编辑

               4° DATE(datetime) : 返回当前时间的日期部分;
               
DATE_ADD(date, INTERVAL d_value d_type) : 在当前日期的基础上加上一段时间或日期;
               
DATE_SUB(date, INTERVAL d_value d_type) : 在当前日期的基础上减去一段时间或日期;

               先来建一张新闻消息表,代码如下:

CREATETABLE IF NOT EXISTS `timetable`(  `id` MEDIUMINTNOTNULL DEFAULT 0,  `name` VARCHAR(50)NOTNULL DEFAULT '',  `send_time` TIMESTAMPNOTNULL DEFAULT CURRENT_TIMESTAMP 
ONUPDATE CURRENT_TIMESTAMP
);INSERTINTO `timetable`
VALUES(1,'震惊,XXX','2023-5-14 10:35:22'),(2,'卧槽,XXX','2023-5-14 10:36:42'),(3,'我趣,XXX','2023-5-14 10:40:12');SELECT*FROM `timetable`;

image.gif

               消息表如下 :

image.png

image.gif编辑

               现要求——

               ①取出name中含有卧槽的新闻及其发布时间,且发布时间仅要求日期;

SELECT `name`,DATE(`send_time`)FROM `timetable`
WHERE `name` LIKE'卧槽%';

image.gif

image.png

image.gif编辑

               ②取出20分钟内发布的新闻;

/*    WHERE子句的含义是要求发布时间 + 20分钟后大于当前时间的新闻,    即20分钟内发布的新闻。*/# 思路一 :SELECT*FROM `timetable`
WHERE DATE_ADD(`send_time`, INTERVAL 20 MINUTE)>= NOW();# 思路二 :SELECT*FROM `timetable`
WHERE DATE_SUB(NOW(), INTERVAL 20 MINUTE)<= `send_time`;

image.gif

image.png

image.gif编辑

                DATEDIFF(date1, date2) : 返回两个日期的时间差,结果是天;

               8° TIMEDIFF(date1, date2) : 返回两个时间的时间差,结果是时间;

# 求一个2002-1-1日出生的人,活到120岁还能活几天
SELECT DATEDIFF(DATE_ADD('2002-1-1', INTERVAL 120YEAR),DATE(NOW()))FROM DUAL;# 求时间差
SELECT TIMEDIFF('20:14:44','14:22:11')FROM DUAL;

image.gif

image.png

image.gif编辑

image.png

image.gif编辑

               10° UNIX_TIMESTAMP() : 返回1970-1-1到现在的秒数。

               11° FROM_UNIXTIME() : 返回年月日。实际开发中,可能会使用int类型来保存一个时间戳,然后使用FROM_UNIXTIME()函数进行转换。

SELECT UNIX_TIMESTAMP(),      FROM_UNIXTIME(UNIX_TIMESTAMP(),'%Y-%m-%d %H:%i:%s')AS `STAMP`
FROM DUAL;

image.gif

image.png

image.gif编辑


八、加密函数

       1.基本语法 :

       1°SELECT USER()FROM table_name;        ——查询当前登录到MySQL的用户及其IP;

       SELECT DATABASE();         ——查询当前使用的数据库名称;

       SELECT MD5(str);         ——根据当前字符串,通过MD5特定算法得到一个32位的密码,常用于对数据库用户密码的加密,并且数据库中保存的用户密码,往往就是MD5加密后的密码;

       SELECT * FROM mysql.user; ——查询mysql数据库中的所有用户。

       2.代码演示 :

               SELECT USER()FROM table_name;

               SELECT DATABASE();

SELECT USER(), DATABASE();

image.gif

image.png

image.gif编辑

               SELECT MD5(str);

SELECT MD5('123456'), MD5('2333');CREATETABLE IF NOT EXISTS `test_users`(  `id` MEDIUMINTNOTNULL DEFAULT 0,  `name` VARCHAR(32)NOTNULL DEFAULT '',  `pwd` CHAR(32)NOTNULL DEFAULT '');INSERTINTO `test_users`
VALUES(11,'Cyan', MD5('123456')),(12,'Raina', MD5('2333'));SELECT*FROM `test_users`
WHERE `pwd` = MD5('123456')OR `pwd` = MD5('2333');

image.gif

image.png

image.gif编辑

image.png

image.gif编辑

               SELECT * FROM mysql.user; ——查询mysql数据库中的所有用户

SELECT*FROM mysql.user;

image.gif

image.png

image.gif编辑


九、 流程控制函数

       1.基本语法 :

       SELECT IF(expr_1, expr_2, expr_3)FROM table_name; ——若expr_1为TRUE则返回expr_2,否则返回expr_3)。(相当于java中的三目运算符)

       SELECT IFNULL(expr_1, expr_2)FROM table_name; ——若expr_1为NULL,返回expr_2,否则返回expr_1)。

       SELECTCASE WHEN expr_1 THEN expr_2

                                     WHEN expr_3 THEN expr_4...

                                     WHEN expr_n-1 THEN expr_n

                                     ELSE expr_e END; ——若expr_1成立,则返回expr_2;若expr_3成立,则返回expr_4,依此类推;若所有条件都不成立,返回ELSE中的内容。(相当于java中自带break语句的case分支语句)。

       2.代码演示 :

               SELECT IF(expr_1, expr_2, expr_3)FROM table_name;

               2°SELECT IFNULL(expr_1, expr_2)FROM table_name;

SELECT IF(2<3,'haha','wuwu')AS `if_1`,       IF(2>3,'hah','wuwuw')AS `if_2`,       IFNULL(NULL,2333)AS `ifnull_1`,       IFNULL(666,2333)AS `ifnull_2`;

image.gif

image.png

image.gif编辑

               SELECTCASE WHEN expr_1 THEN expr_2

                                     WHEN expr_3 THEN expr_4...

                                     WHEN expr_n-1 THEN expr_n

                                     ELSE expr_e END;

SELECT `name`, `sex`, `English`, `Math`,(SELECT CASE WHEN `sex` ='female' THEN 'woman'            WHEN `sex` ='male' THEN 'man'            ELSE 'unknown' END)AS `test`
FROM `stus`;

image.gif

image.png

image.gif编辑

       System.out.println("END-----------------------------------------------------------------------------");

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
2月前
|
JSON 关系型数据库 MySQL
Mysql(5)—函数
MySQL提供了许多内置的函数以帮助用户进行数据操作和分析。这些函数可以分为几类,包括聚合函数、字符串函数、数值函数、日期和时间函数、控制流函数等。
93 1
Mysql(5)—函数
|
2天前
|
SQL 关系型数据库 MySQL
【MySQL基础篇】盘点MySQL常用四大类函数
本文介绍了MySQL中的四大类常用函数:字符串函数、数值函数、日期函数和流程函数。
【MySQL基础篇】盘点MySQL常用四大类函数
|
18天前
|
SQL 关系型数据库 MySQL
MySQL常见函数第二期,你都用过哪些呢 ?
本期介绍了20个常用的MySQL函数,涵盖日期处理(如CURDATE()、DATE_FORMAT())、数学运算(如ABS()、ROUND())、统计分析(如COUNT()、SUM())等,帮助提高SQL查询效率和数据处理能力。希望对大家的学习有所帮助。
60 7
|
21天前
|
关系型数据库 MySQL
MySQL常见函数第一期,你都用过哪些呢 ?
本期介绍10个常用的MySQL函数:字符串连接(CONCAT)、提取子字符串(SUBSTRING)、获取字符串长度(LENGTH)、转换大小写(UPPER、LOWER)、去除空格(TRIM)、替换字符串(REPLACE)、查找子字符串位置(INSTR)、带分隔符的字符串连接(CONCAT_WS)以及获取当前日期时间(NOW)。
56 8
|
22天前
|
数据采集 关系型数据库 MySQL
MySQL常用函数:IF、SUM等用法
本文介绍了MySQL中常用的IF、SUM等函数及其用法,通过具体示例展示了如何利用这些函数进行条件判断、数值计算以及复杂查询。同时,文章还提到了CASE WHEN语句和其他常用函数,如COUNT、AVG、MAX/MIN等,强调了它们在数据统计分析、数据清洗和报表生成中的重要性。
|
26天前
|
关系型数据库 MySQL 数据处理
【MySQL】函数
MySQL 提供了丰富的函数集,涵盖字符串处理、数值运算、日期时间操作和聚合计算等多个方面。这些函数在日常数据库操作中极为重要,通过合理使用这些函数,可以大大提高数据处理和查询的效率。用户还可以通过自定义函数,扩展 MySQL 的功能以满足特定需求。
28 3
|
28天前
|
关系型数据库 MySQL 数据处理
MySQL函数与约束
MySQL 提供了丰富的函数和强大的约束机制,用于数据处理和完整性维护。通过掌握这些工具,可以有效地管理和分析数据库中的数据,确保数据的一致性和准确性。无论是在日常数据查询中使用内置函数,还是在数据库设计中应用各种约束,都是确保数据库系统稳定、高效运行的关键。希望本文对您理解和应用 MySQL 函数与约束有所帮助。
31 1
|
1月前
|
关系型数据库 MySQL Serverless
MySQL函数
最常用的MySQL函数,包括聚合函数,字符串函数,日期时间函数,控制流函数等
37 1
|
2月前
|
存储 SQL 关系型数据库
MySQL 存储函数及调用
MySQL 存储函数及调用
207 3
|
1月前
|
SQL NoSQL 关系型数据库