精华内容
下载资源
问答
  • mysql 数据库快速入门 数据库的发展

    千次阅读 2019-01-03 09:58:04
    数据库技术是通过研究数据库的结构、存储、设计、管理以及应用的基本理论和实现方法,并利用这些理论来实现对数据库中的数据进行处理、分析和理解的技术。即:数据库技术是研究、管理和应用数据库的一门软件科学。 ...

    数据库概述

    数据库技术是通过研究数据库的结构、存储、设计、管理以及应用的基本理论和实现方法,并利用这些理论来实现对数据库中的数据进行处理、分析和理解的技术。即:数据库技术是研究、管理和应用数据库的一门软件科学

    数据库的目的

    其主要目的是有效地管理和存取大量的数据资源.数据库技术主要研究如何存储,使用和管理数据

    数据库基本概念

    • 主要包括:信息,数据,数据处理,数据库,数据库管理系统以及数据库系统等。
    • 数据库技术研究和解决了计算机信息处理过程中大量数据有效地组织和存储的问题,在数据库系统中减少数据存储冗余、实现数据共享、保障数据安全以及高效地检索数据和处理数据。数据库技术的根本目标是要解决数据的共享问题。

    数据库的发展

    数据管理技术是对数据进行分类,组织,编码,输入,存储,检索,维护和输出的技术.数据管理技术的发展大致经过了以下三个阶段:

    1. 人工管理阶段
    2. 文件系统阶段
    3. 数据库系统阶段

    数据库的数据模型

    数据模型的概念及要素数据模型是现实世界在数据库中的抽象,也是数据库系统的核心和基础.数据模型通常包括3个要素。

    1. 数据结构 :数据结构主要用于描述数据的静态特征,包括数据的结构和数据间的联系。
    2. 数据操作 : 数据操作是指在数据库中能够进行的查询,修改,删除现有数据或增加新数据的各种数据访问方式,并且包括数据访问相关的规则。
    3. 数据完整性约束 : 数据完整性约束由一组完整性规则组成。

    常见数据库数据模型

    1. 层次模型(Hierarchical Model).层次模型使用树形结构来表示数据以及数据之间的联系。
    2. 网状模型(Network Model).网状模型使用网状结构表示数据以及数据之间的联系。
    3. 关系模型(Relational Model).关系模型是一种理论最成熟,应用最广泛的数据模型.在关系模型中,数据存放在一种称为二维表的逻辑单元中,整个数据库又是由若干个相互关联的二维表组成的

    补充:

    比较成熟的软件产品能够很好地支持关系型数据模型,这些产品也因此称为关系型数据库管理系统(Relational DataBase Management System,RDBMS)

    • 微软公司的Microsoft Access 、MS-SQL Server
    • Sybase公司的Sybase
    • 甲骨文公司的Oracle
    • IBM公司的DB2

    数据库的发展历史

    数据库的发展和数据模型的发展不可分开,以数据模型为径,数据库发展可以这么说:

    1. 第一代 : 网状和层次数据库系统。
    2. 第二代 : 关系数据库系统。
    3. 第三代 : 以面向对象数据模型为主要特征的数据库系统。

    基本名词

    • 数据(Data)是用于描述现实世界中各种具体事物或抽象概念的,可存储并具有明确意义的符号,包括数字,文字,图形和声音等。
    • 数据处理是指对各种形式的数据进行收集,存储,加工和传播的一系列活动的总和.其目的之一是从大量的,原始的数据中抽取。
    • 数据库(DataBase,DB)是存储在计算机辅助存储器中的,有组织的,可共享的相关数据集合。
    • 数据库管理系统(DataBase Management System,DBMS)是对数据库进行管理的系统软件,它的职能是有效地组织和存储数据,获取和管理数据,接受和完成用户提出的各种数据访问请求.能够支持关系型数据模型的数据库管理系统,称为关系型数据库管理系统(Relational DataBase Management System,RDBMS)。
    • 结构化查询语言(Structured Query Language,SQL)来实现的,SQL是关系数据库中的一种标准语言,在不同的RDBMS产品中,SQL中的基本语法是相同的.此外,DDL,DML,DQL和DCL也都属于SQL

    RDBMS的基本功能

    • 数据定义功能:RDBMS提供了数据定义语言(Data Definition Language,DDL),利用DDL可以方便地对数据库中的相关内容进行定义.例如,对数据库,表,字段和索引进行定义,创建和修改。
    • 数据操纵功能:RDBMS提供了数据操纵语言(Data Manipulation Language,DML),利用DML可以实如今数据库中插入,修改和删除数据等基本操作。
    • 数据查询功能:RDBMS提供了数据查询语言(Data Query Language,DQL),利用DQL可以实现对数据库的数据查询操作。
    • 数据控制功能:RDBMS提供了数据控制语言(Data Control Language,DCL),利用DCL可以完成数据库运行控制功能,包括并发控制(即处理多个用户同时使用某些数据时可能产生的问题),安全性检查,完整性约束条件的检查和执行,数据库的内部维护(例如索引的自动维护)等。
    展开全文
  • 数据库概述数据库入门

    千次阅读 2019-04-20 12:20:15
    数据库概述 数据库入门 数据库概述 存放数据的方式 1.存在内存中 2.保存在普通文件中 3.保存在数据库中 什么是数据库 存储数据的仓库,用户可以对数据库中的数据进行增加,修改,删除及查询操作(sql...

    数据库概述 数据库入门

    数据库概述

    存放数据的方式

    • 1.存在内存中
    • 2.保存在普通文件中
    • 3.保存在数据库中

    什么是数据库

    存储数据的仓库,用户可以对数据库中的数据进行增加,修改,删除及查询操作(sql语言)。

    数据库的优点-

    数据库是按照特定的格式将数据存储在文件中,通过SQL语句可以方便/*-的对大量数据进行增、删、改、查操作,数据库是对大量的信息进行管理的高效的解决方案。-

    数据库管理系统(DBMS)

    数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于创建、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系 统访问数据库中表内的数据

    数据库管理系统、数据库和表的关系

    数据库管理系统可以管理多个数据库,每个数据库中可以有多张数据库表。

    常见数据库

    • MYSQL:开源免费的数据库,小型的数据库.已经被Oracle收购了.MySQL6.x版本也开始收费。
    • Oracle:收费的大型数据库,Oracle公司的产品。Oracle收购SUN公司,收购MYSQL。
    • DB2:IBM公司的数据库产品,收费的。常应用在银行系统中.
    • SQLServer:MicroSoft 公司收费的中型的数据库。C#、.net等语言常使用。
    • SyBase:已经淡出历史舞台。提供了一个非常专业数据建模的工具PowerDesigner。
    • SQLite: 嵌入式的小型数据库,应用在手机端。

    安装MySql数据库

    卸载: 使用软件管理工具,手动删除 
    
    细节:不止要删除数据库,还要将保存数据的文件给手动删除了,如果不删除无法正常安装新的数据库
    

    启动和关闭mysql

    细节注意:mysql的服务必须是启动状态下才是使用

    • 启动和关闭mysql:
      • 方式1:操作windows服务
      • 方式2:dos命令中操作mysql
        • net start mysql 开启mysql服务
        • net stop mysql 停止mysql服务

    登录和退出mysql数据库

    第一种:

    • mysql -u用户名 -p密码
      例如:mysql -uroot -proot

    第二种

    • mysql -u用户名 -p
    • 密码

    退出

    • exit
    • quit
    • ctrl + c

    sql语句

    简介

    概述

    结构化查询语言(Structured Query Language)简称SQL,SQL语句就是对数据库进行操作的一种语言。
    

    数据库是不认识JAVA语言的,但是我们同样要与数据库交互,这时就需要使用到数据库认识的语言—SQL语言

    作用:

    通过Sql语言可以对数据库管理系统中的数据库,表,表中的数据进行增删改查(crud)。
    
     

    sql分类和语法

    分类:(面试题)

    1.DDL(Data Definition Language)数据定义语言

     用来操作数据库和表
    

    关键字:create,drop,alter等

    2.DML(Data Manipulation Language)数据操作语言

    用来对数据库中表的数据进行增删改
    

    关键字:insert,delete, update等

    3.DQL(Data Query Language)数据查询语言

    用来对数据库中表的数据进行查询
    

    关键字:select,from,where等

    4.DCL(Data Control Language)数据控制语言(了解)

    用来定义数据库的访问权限和安全级别,及创建用户。
    

    关键字:grant, revoke等

    5.TCL(Transaction Control Language) 事务控制语言

    用于控制数据库的事务操作
    

    关键字: commit,rollback等

    sql语法

    1 SQL语句可以单行或多行书写,以分号结尾
    2 可使用空格和缩进来增强语句的可读性
    3 MySQL数据库的SQL语句不区分大小写
    4 可以使用-- 或# 或/**/的方式完成注释

    DDL(数据定义语言)

    操作数据库

    1-创建数据库

    创建数据库 (掌握)

    create database 数据库名;
    

    默认字符集是安装mysql时选择的字符集 (utf8)

    判断是否存在并创建数据库(了解)

    create database if not exists 数据库名;
    
     

    创建数据库并指定字符集(了解)

    create database 数据库名 character set 字符集;
    
     

    2-查询数据库

    查询所有数据库

    show databases;
    
     

    查看某个数据库的定义信息

     show create database 数据库名称;
    
     

    3-修改数据库(了解)

    修改数据库字符集格式

    alter database 数据库名  character set 字符集;
    
     

    4-删除数据库

    drop database 数据库名;
    
     

    5-数据库的其他操作

    查看当前使用的数据库

    select database();
    
     

    切换数据库

    use 数据库;
    
     

    操作表

    条件:首先要进入到指定的数据库中

    创建表

    create table 表名(
    字段名1 字段类型1[长度],
    字段名2 字段类型2[长度]   
    .....
    )
    ps:只有字符串类型需要手动加长度,其它类型都不需要加长度(默认有)
    

    – 需求: 创建一个学生表(id name sex)

    数据类型:
    java的数据类型 mysql数据库的数据类型
    int int
    float float
    double double

    char/string varchar
    date date yyyy-MM-dd
    time HH:MM:SS
    datetime YYYY-MM-DD HH:MM:SS

    查看表

    查看某个数据库中的所有表:  show tables;
    

    查看表结构: desc 表名称;

    查询建表语句: show create table 表名;

    快速创建表结构: create table 新表名 like 旧表名;

    修改表结构

    添加表列 :   alter table 表名 add 列名 类型;
    

    删除表列 : alter table 表名 drop 列名;

    修改列名 : alter table 表名 change 旧名称 新名称 类型;

    修改列类型 : alter table 表名 modify 列名 新类型

    修改表名称 : rename table 旧表名 to 新表名;

    删除表

    直接删除表: drop table 表名;
    

    判断表是否存在并删除表(了解): drop table if exists 表名;

    DML(数据操作语言)–重点

    插入记录

    添加全部字段

    方式一:insert into 表名 (字段名1, 字段名2, 字段名3…) values (值1, 值2, 值3);    
    

    方式二:insert into 表名 values (值1, 值2, 值3);

    添加部分字段

    insert into 表名 (字段名1, 字段名2, ...) values(值1, 值2, ...);
    
     

    注意事项

    值与字段必须对应,个数相同,类型相同
    

    值的数据大小必须在字段的长度范围内

    除了数值类型外,其它的字段类型的值必须使用引号引起。

    如果要插入空值,可以不写字段,或者插入null

    DOS命令窗口操作数据乱码问题的解决(了解)

    • 错误说明:
      当我们使用DOS命令行进行SQL语句操作如有有中文会出现乱码,导致SQL执行失败
    • 错误原因:
      因为MySQL的设置编码是utf8,而系统的DOS命令行编码是gbk,编码不一致导致的乱码
    • 解决方案:
      设置mysql编码方式
      • 快捷设置(临时)
        set names gbk;
      • 修改配置文件(永久)
        1 my.ini文件,在[mysql]设置字符集:GBK
        2 重启mysql服务

    蠕虫复制

    在已有的数据基础之上,将原来的数据进行复制,插入到对应的表中

    前提:表结构得一致

    语法格式: insert into 新表 select * from 旧表;
    
     

    修改记录

    不带条件修改数据 : update 表名 set 字段名 = 值,字段名 = 值 ;  全改
    

    根据条件修改数据 : update 表名 set 字段名 = 值,字段名 = 值 where 字段名=值; 按条件改

    删除记录

    不带条件删除数据: delete from 表名;   全删
    

    根据条件删除数据: delete from 表名 where 字段名=值; 按条件删

    truncate删除表记录: truncate 【table】 表名; 全删

    truncate和delete的区别:(面试题)

    delete是将表中的数据一条一条删除

    truncate是将整个表摧毁,重新创建一个新的表,新的表结构和原来表结构一模一样

        delete删除的数据可以还原  truncate的数据无法还原
    

    DQL(数据查询语言)

    简单查询:

    查询所有列:  select * from 表名;
    

    查询指定列: select 字段名1,字段名2… from 表名;

    别名查询: select 字段名1 as 别名, 字段名2 as 别名… from 表名 as 表别名;

    清除重复值: select distinct 字段名 from 表名;

    查询结果参与运算: select 列名1 + 固定值 from 表名;(参数运算的字段必须为数值型)

    1 查询所有的商品
    2 查询商品名称和商品价格
    3 使用别名查询商品:as as可以省略
    4 去重查询 查询去重之后的价格 distinct
    5 运算查询 查询价格,将价格的增加100

    总结

    1 数据库的概念 
       用来存储数据的仓库,仓库需要DBMS系统创建,在硬盘上,所有数据也在硬盘上
       要想操作仓库中的数据,必须得使用sql语句
    2 DBMS系统的安装
        mysql    见参考大纲  细节:卸载
        oracle
        db2
        sqlserver
    3 sql语句操作数据库
         1 使用sql语句告诉dbms系统做数据库的crud      ddl分类
         2 使用sql语句告诉dbms系统做数据库表的crud    ddl分类
         3 使用sql语句告诉dbms系统做数据库表上数据的增删改 dml分类
         4 使用sql语句告诉dbms系统做数据库表上数据的查     dql分类
            简单查询
    
     

    《算法导论 第三版英文版》_高清中文版

    《深度学习入门:基于Python的理论与实现》_高清中文版

    《深入浅出数据分析》_高清中文版

    《Python编程:从入门到实践》_高清中文版

    《Python科学计算》_高清中文版

    《深度学习入门:基于Python的理论与实现》_高清中文版

    《深入浅出数据分析》_高清中文版

    《Python编程:从入门到实践》_高清中文版


    展开全文
  • 数据库设计入门

    千次阅读 2013-07-07 07:54:01
    实际开发中,少不了要和各种数据库打交道,一般说来,传统的关系型数据库使用方式主要有两种,一是普通用户通过命令行接口直接访问数据库,建立各种表格,维护这些表格(增、删、查、改),使用SQL语言基于数据生成...


    *注:本文大量引用了参考文献所列资料中的图片和知识,在此对这些文章和网站的作者表示由衷的感激,是你们的分享让我学到了很多知识。

    实际开发中,少不了要和各种数据库打交道,一般说来,传统的关系型数据库使用方式主要有两种,一是普通用户通过命令行接口直接访问数据库,建立各种表格,维护这些表格(增、删、查、改),使用SQL语言基于数据生成各种报告;二是程序员基于数据库API抽象和封装特定于应用的数据库访问模式,实现对数据库的访问。两种方式都有各自的难点——前者难在数据建模上,良好的数据建模使得数据库中的表格易于维护,糟糕的设计则会产生不必要的冗余和使用上的蹩脚;后者难在访问模式的设计上,同样,好的设计使得接口易于扩展,不好的设计使得代码难以维护。因此,抓住两个中心点,良好的数据模型和数据访问模式,本文就从这两个方面展开,谈一谈自己在学习过程中的一些体会,若读者诸君能从本文中找到笔者思维上的盲点和文章中的错误,非常感激您能够不吝赐教;若读者诸君能够通过本文得到一点点的启发,则又幸矣。

    一.   数据库设计

    数据库设计是一门艺术,这里的数据库设计主要是指选用某关系型数据库的产品,然后在此基础上根据需求设计表格,这些相互关联的表格构成了我们需要的“数据库”,这里以一个非常简单的网上书店应用作为数据库设计的例子,介绍数据设计的一些入门知识。

    1   数据建模

    做任何事情之前都要先明确目标,数据建模也不例外。建模的第一步就是明确自己的目标。明确目标之后要考虑的就是想要捕捉哪些数据,也就是实体抽象。模型就是一种抽象,通过建模,我们把客观世界中我们感兴趣的对象身上的某些属性抽取出来,忽略掉其他的一些属性,建立它们的模型。

    1.1 主键的选择

    设计表格的同时,还要考虑表格之间可能的关联,因为表格之间如果没有相互关联的话,数据库的威力就要大打折扣了。要在数据库之间建立关系,主要是靠“键”,键有两种,分为主键和外键。主键用于唯一地标识表格中的一条记录,消除二义性;而外键则用于引用其他表的主键,这样表之间的关联就建立起来了。主键可以是一个属性,也可以是属性的组合(复合主键),关于主键的选取,并没有绝对的法则,Fabian Pascal在《SQL and Relational Basics》中提到,主键的设计决策要参考三个原则:

    l  最小化原则:用最少的列作为主键;

    l  稳定性原则:作为主键的列很少被修改;

    l  简单/熟悉原则:作为主键的列既简单又被用户所熟悉。

    除以上三个原则外,对键的设计还有一个经验之谈——尽量使用整数的数值类型作为主键,比如学号,数值类型的列比文本容易处理,且考虑到有时候姓名、地址这类文本信息有输入错误和发生重复的可能(比如一家人分别下单,派送地址都一样,那么地址虽然唯一,但在这里就不适合作为主键)这样数据就被简单归类为三个实体,如图1.2所示。

    1.1.1 建立联系

    有了主键和外键,我们就有了设计表之间关联关系的基础,现实世界中的实体之间的关系常常是错综复杂的,反映到数据模型中,我们就需要在表格之间建立联系,主要是三种:一对一、一对多和多对多。

    1)一对一关系

    如果对于第一张表中的每一条记录,在第二张表中最多存在一条记录与其相对应,则称两张表为一对一关系。现实世界中一对一关系很少,这种关系模式主要用于对信息访问加以限制,比如医院数据库中使用表Patients_TBL来维护病人信息,但可能使用Confidential_TBL来存放敏感信息(姓名,身份证号和住址等等),这两张表中每条记录都是针对同一个病人的,因此主键都是PatientId,且一一对应。

    2)一对多关系

    如果对于第一张表中的每一条记录,在第二张表中有0个,1个或多条记录与之相对应;同时,对于第二张表中的每一条记录,在第一张表中仅有一条记录与之相对应,则称两张表为一对多关系。比如披萨店的订单可能会订各种口味的披萨饼,那么Order_TBL和OrderDetail_TBL之间就是一对多的关系。一对多关系通常也被称为“父-子”关系,它是三种关系中最常见的。

    3)多对多关系

    如果对于第一张表中的每一条记录,在第二张表中都有多条记录与之相对应;同时,对于第二张表中的每一条记录,在第一张表中都有多条记录与之相对应,则称两张表为多对多关系。多对多关系在数据库中不能被直接建模,它常常被设计为两个一对多关系——通过增加一个连接表。比如一位顾客可能买了多个保险公司的保险,而一个保险公司同时也拥有多个顾客,因此Cutomers_TBL和Insurers_TBL之间就是多对多的关系,此时通过建立一张连接表CustInsurance_TBL将两张表变为两个一对多关系:一个顾客购买了0个,1个或多个保险;与此同时保险公司出售的保险也是这样一个关系。

    1.1.2设计范式

             数据库建模有很多范式,一级比一级高,这里只介绍前三种:第一、第二和第三范式。范式的使用主要是为了在各个层面各个阶段尽量消除数据的冗余。满足第N范式的数据库一定先满足第N-1范式。但正如前文所说的,数据库设计是一门艺术,有时候不是必须要严格遵守这些范式,反而适当的数据冗余能够提高查找效率,这个是需要特别注意的,因此数据库设计常常不是一蹴而就的,需要逐步精炼和反复设计。

    1)第一范式(1NF)

    1NF:所有列值必须是原子的(不可分解)

           在“Fundamentals of Relational Database Design”中介绍了这么一个例子,如图1.1所示。该表的设计不满足第一范式,因为很明显Items列并不是原子的,不仅将购买数量和购买工具名称放在一起,且一列中存放了多个工具的信息,因此要分解该列,使得所有的列值都变成不可分割的,就像图1.2展示的那样。

           但这样的表格还是有问题,因为每条记录都只包含了Item1、Item2和Item3,万一顾客要买5件,6件工具怎么办?朴素的方法是将一条记录扩展成Item1到Item6,但是下次碰到买9件工具的客户呢?20件工具的客户呢?从这里可以看出,表设计的弊端在于非必要地限定购买量,且多个ItemX列和QuanX列实际上是重复的,所以还需要改造成图1.3的样子——所有的ItemX和QuanX列合并为Item列和Quantity列,每条记录仅描述一种购买的工具。所以实际上第一范式除了要求列值是原子的以外,还要求列没有重复组。

    2)第二范式

    2NF:每一个非键的列都完全依赖于整个主键

    通俗地说,第二范式要求主键能够描述表中每一条记录中的每一列。通过一个主键能够决定全部的其他列,而不是部分列。图1.4中的表为OrderId和OrderItem#构成的联合主键。虽然满足1NF,但并不满足2NF——给定OrderId,可以知道CustomerId和OrderDate,并不需要OrderItem#;反之,给定OrderItem#,可以知道Quantity,ProductId和ProductDescription信息,不需要OrderId参与。解决方法就是——分解,将订单表分解为订单和订单明细即可,其中订单明细中的OrderId为外键,如图1.5所示。

    3)第三范式

    3NF:所有非键列都是互相独立的

           也就是说,不作为键的列之间不存在依赖关系,最常见的就是,一般情况下不要存储可以依赖其他列计算出值的列,比如表中不要有计算总和的列——应该用SQL语句来计算生成。但是,有时候为了提高查询效率,可以适当地违反3NF,存储一些计算值以提高速度。非计算依赖的例子也有,比如图1.5中的订单细节表中ProductId和ProductDescription就是相互依赖的列,每次修改前者时,都要把后者更新一次。解决的办法仍然是分表,将ProductId与ProductDescrption的对应关系分离出来形成查找表tblProduct,此时前者成为该表的主键和订单细节表的外键,如图1.6所示。

    1.2 完整性规则

             完整性规则有两类:一般完整性规则和数据库特有的完整性规则。一般完整性规则又分为两种——实体完整性和引用完整性。前者要求数据库的主键不能为空值(NULL);后者要求数据库的外键不能包含任何不匹配的外键值,即:

    l  除非被引用的记录存在,否则无法向一个包含外键的表中添加记录;

    l  若被引用的记录被修改或删除,外键所在的表对应的记录不能变成“孤儿”。

    所以,数据库就有了三种选项来保证引用完整性。Disallow使得这样的改变完全不允许;Cascade要求一个表中的变化被同步到其他表中;而 Nullify使得删除操作把外键置空。

    数据库特有的完整性规则又称为业务规则,是与具体的应用相关的,它在一定程度上防止坏数据进入数据库,比如管理订单的数据库,派送日期应该在下单日期之后,用户购买的数量不能是负值等等,它是业务逻辑意义上的“合法性约束”。

    1.3 一个简单的数据库设计

    下面,我们来为网上书店建立一个很简单的关系型数据库,设计数据库的第一步就是要明确自己的目标,因此设计之初我们只有一个朴素的想法,如图1.7所示。

    考虑得简单一些的话,我们肯定需要知道书店都有哪些书,书名叫什么,有多少本,售价几何,作者是谁等等,很自然地,就应该有一张表格来存放书籍的这类信息(一张表格只负责一种职责,只描述一种信息);用户要来买书,我们要把书送到人家手上,就要有派送地址,需要记录用户的姓名,年龄,地址等信息,那么维护客户信息的表也是必不可少的;除此之外,还需要一个“订单”表,用于维护用户每次的购买记录。表的初步设计就是考虑捕捉我们感兴趣的一些信息,然后进行实体抽象和简单的归类。从图1.8可以看出,订单表的设计有些问题,没有下单日期,因此要添加,且该表不满足第二范式,主键的依赖性不是完全的,需要做分表,图1.9为进一步修改后的设计。订单表还是有问题 ,quantity应该放到订单细节表中,因为book_id 可以决定某本书买了多少本,且quantity可以有一个为1的默认值(通常情况下顾客只会买一本),此外,一个book_id不足以做订单细节的主键,因为多个顾客可能会买同一本书,在这种情况下,一个book_id就会对应多条记录,因此这个表应该是book_id和order_id做联合主键,如图1.10所示。

    进一步理论联系实际后发现,订单细节表和书籍表设计有问题,price冗余是第一个原因,第二个原因是,订单细节里的price应该理解为原价乘以折扣后的实际售价,所以订单细节里的price依赖于discount,应当去掉。最后得到图1.11所示的数据库。

    这里要说明的是,这种简单到近乎幼稚的数据库在现实生产环境中是不存在的,真实的数据库设计往往需要对需求和业务的深入理解和长时间的精炼以及反复设计,因此数据库设计是一门艺术,要在实际工作中才能逐步掌握。

    1.4 SQL建表

    下面该将图表中的数据模型转换成真实的表格了,通过一些工具可以自动生成对应的SQL语句,我们的数据库对应的SQL语句如代码清单1-1所示。

    代码清单1-1

    CREATE  TABLE IF NOT EXISTS `xxx`.`Customers_TBL` (
      `customer_id` INT NOT NULL ,
      `first_name` VARCHAR(32) NOT NULL ,
      `last_name` VARCHAR(32) NOT NULL ,
      `age` INT NULL ,
      `address` VARCHAR(45) NOT NULL ,
      `phone_num` INT NOT NULL ,
      PRIMARY KEY (`customer_id`) )
    ENGINE = MyISAM DEFAULT CHARSET = utf8
    
    CREATE  TABLE IF NOT EXISTS `xxx`.`Orders_TBL` (
      `order_id` INT NOT NULL ,
      `customer_id` INT NOT NULL ,
      `date` DATETIME NOT NULL ,
      `delivery_address` VARCHAR(45) NULL ,
      PRIMARY KEY (`order_id`) ,
      KEY `customer_id` (`customer_id`),
      CONSTRAINT `customer_id_fk`
        FOREIGN KEY (`customer_id` )
        REFERENCES `xxx`.`Customers_TBL`(`customer_id`)
        ON DELETE CASCADE
        ON UPDATE CASCADE )
    ENGINE = MyISAM DEFAULT CHARSET = utf8
    
    CREATE  TABLE IF NOT EXISTS `xxx`.`Orders_Detail_TBL` (
      `order_id` INT NOT NULL ,
      `book_id` INT NOT NULL ,
      `discount` DECIMAL(2,2) NULL ,
      `quantity` INT NULL DEFAULT 1 ,
      PRIMARY KEY (`order_id`, `book_id`) ,
      INDEX `fk_Orders_Detail_TBL_Orders_TBL1_idx` (`order_id` ASC) ,
      CONSTRAINT `order_id`
        FOREIGN KEY (`order_id` )
        REFERENCES `xxx`.`Orders_TBL` (`order_id` )
        ON DELETE CASCADE
        ON UPDATE CASCADE)
    ENGINE = MyISAM DEFAULT CHARSET = utf8
    
    CREATE  TABLE IF NOT EXISTS `xxx`.`Books_TBL` (
      `book_id` INT NOT NULL ,
      `isbn` VARCHAR(64) NOT NULL ,
      `title` VARCHAR(45) NOT NULL ,
      `author_first_name` VARCHAR(45) NULL ,
      `author_last_name` VARCHAR(45) NULL ,
      `num` INT NOT NULL ,
      `price` DECIMAL(6,2) NOT NULL ,
      INDEX `fk_Books_TBL_Orders_Detail_TBL1_idx` (`book_id` ASC) ,
      PRIMARY KEY (`book_id`) ,
      CONSTRAINT `book_id_fk`
        FOREIGN KEY (`book_id` )
        REFERENCES `xxx`.`Orders_Detail_TBL` (`book_id` )
        ON DELETE CASCADE
        ON UPDATE CASCADE)
    ENGINE = MyISAM DEFAULT CHARSET = utf8
    

    2   访问数据库

    好吧,终于走到主题了,接下来的内容终于从数据库建模走到了编程,我们来看看怎样用经典的“数据访问对象”(Data Access Object)来访问数据库。DAO只是数据访问模式的一种,根据具体的应用场景会有各种不同的访问模式,关键是要根据情况选择合适的技术方案。

    2.1 DAO模式介绍

             “数据访问对象”模式由一系列相关的类共同构成。一个典型的应用通常有三层:展现层、业务逻辑层和数据访问层。数据访问层的数据源是不同的——它们可能是不同厂商的数据库产品,可能是WebService,也可能是XML文件,不仅不同的数据库产品之间存在差别,而且不同数据源的访问方式也不同。DAO模式抽象并对业务逻辑层隔离了这种数据源的相异性,它“知道”如何跟各种不同数据源打交道,且提供的接口使得应用程序不需要了解与之交换信息的数据源究竟是什么样的,所以,总结一下,我们得出这样的结论:DAO模式通过“分离职责”,将数据源接口和数据访问机制分开,使特定API应用于一般接口成为可能(颇有适配器模式的味道)。原则上数据访问对象并不需要知道太多所存储的数据的细节,该细节由它的好搭档——被称为DTO的“数据传输对象”来负责。

    2.2 DTO模式介绍

    DTO模式的提出是有一定问题背景的,在典型的分布式应用程序中,为了响应单个客户端的请求,应用程序要通过远程调用来访问远端的数据源(可能是数据库,也可能是其他数据源)。如果需要通过多次调用才能满足一个请求,这些调用的响应时间通常会让人难以接受。所有的框架都把远程调用的复杂性对调用者隐藏了,但耗费的时间是无法缩短的,因为这通常包含“定位远程对象——建立连接——发出请求——返回数据”的过程,中间还包括将数据序列化为字节流,加密传输等等。跨网络边界的访问要考虑滞后时间和吞吐量这两个因素,“滞后时间”定义为数据的首字节到达目的地之前经过的时间;“吞吐量”表示单位时间内通过网络发送的字节数。在基于IP路由的网络中,滞后时间往往影响更大,这是网络传输的复杂性所决定的。

    这些因素影响了代码的设计,首先,远程调用的粒度不能太细,细粒度意味着多次调用,这无疑会增加滞后时间;其次,长参数列表并不是很好的设计,参数过多容易导致因疏忽搞错参数次序导致出错,在这样的背景下,DTO模式产生了。

    DTO被设计为具有一系列getter和setter方法的对象,它是待传输数据的代码容器,同时也是数据库记录的一种抽象。使用时,将其作为单一参数调用远程接口,在本地取得DTO对象后对其进行信息存取,这就减少了滞后时间的影响。

    有两种常用的DTO实现方式,第一种针对不同的数据设计具体的类,然后为每个类的属性提供一对getter和setter方法;第二种是使用泛型容器,以“key-value”的形式进行存储。两种方法各有千秋,前者属于强类型,可以实现编译时检查,约束条件检查,但是编写过程枯燥乏味,且对数据很敏感,数据内容和格式的变更往往意味着类的变动;后者属于弱类型,最大的优势是泛型容器总是被不同的编程语言支持,因此使用方便,缺点是按序号或字段访问容易出现细微的错误。

    2.3 DAO编写实践

    介绍完理论背景,我们来看看如何为我们之前设计的在线书店数据库提供数据访问对象。这里编程语言使用C++,且使用MySQL作为数据源。为了避免重复写相同的代码,这里仅以Book类作为例子介绍DAO的编写,首先先来看看相关的类层次结构。

    2.3.1 类层次结构一览

    图1.12展示了类的层次结构,IBookDAO作为接口,定义了对Book类的对象进行存取需要的函数。MysqlDBBookDAO和XMLBookDAO继承了该接口,实现了具体的数据访问机制,只不过一个是使用关系型数据库,而另一个则解析XML文件。如果使用了抽象工厂模式,就可以根据实际需要生成这两种DAO,满足不同的数据存取需要。

    2.3.2 数据传输对象的实现

    Book类作为数据传输对象的职责只有一个,就是对其属性提供一系列的getter()/setter()方法,还可以在setter()方法上加入数据库特有约束检查等等,代码的实现比较简单,这里只提供一个简单的类描述如代码清单2-1所示。

    代码清单2-1

    /*** Data Transfer Object ***/
    class Book {
    public:
    
        Book();
        unsigned int getBookID() const;
        void setBookID(unsigned int bookId);
    
        string getISBN() const;
        void setISBN(string isbn);
    
        string getTitle() const;
        void setTitle(string title);
    
        string getAuthorFirstName() const;
        void setAuthorFirstName(string firstName);
    
        string getAuthorLastName() const;
        void setAuthorLastName(string lastName);
    
        unsigned int getNum() const;
        void setNum(unsigned int nm);
    
        double getPrice() const;
        void setPrice(double price);
    
    private:
        unsigned int bookId;
        string isbn;
        string title;
        string authorFirstName;
        string authorLastName;
        unsigned int num;
        double price;
    };
    


     

    2.3.3 数据访问对象的实现

    代码清单2-2展示了数据访问对象的接口,它主要提供对Book类的增删查改操作,这里只实现了几个基本的函数,实际应用中,应当根据需求提供不同的查询方法,比如根据各种具体条件进行查询的语句,因此这个类是随着需求不断变化的。

    代码清单2-2

    class IBookDAO {
    public:
        // virtual destructor for class hierarchy
        virtual ~IBookDAO() {}
        virtual bool saveBook(Book& book) = 0;
        virtual bool deleteBook(unsigned int bkId) = 0;
        virtual bool updateBook(Book& book) = 0;
        virtual bool getBook(Book& book, unsigned int bkId) = 0;
        virtual list<Book> getAllBooks(unsigned int order) = 0;
    };
    


     

    对MysqlDBBookDAO,我们想设计成这样,首先,数据库相关配置不是直接写在代码中的,而是放入一个XML配置文件,每次DAO启动时,都会读取配置文件并尝试连接数据库;结束时自动释放该连接,这样就可以通过修改配置文件来修改对数据库的访问,而不是每次都去重新编译代码。代码清单2-3展示了这样的一个配置文件。

    代码清单2-3

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <mysqldb>
        <host>localhost</host>
        <username>xxxxxx</username>
        <password>xxxxxx</password>
        <db>xxx</db>
        <port>0</port>
    </mysqldb>
    
    


    下面开始编写MysqlDBBookDAO,代码清单2-4展示了该类的声明。其中四个字符串属性分别用于存储对数据库进行增删查改的SQL语句,通过修改SQL语句就能实现不同的增删查改条件和方式。

    代码清单2-4

    class MysqlDBBookDAO : public IBookDAO {
    public:
        MysqlDBBookDAO();
        MysqlDBBookDAO(const string tbl, const string& configFileName);
        virtual ~MysqlDBBookDAO();
        virtual bool saveBook(Book& book);
        virtual bool deleteBook(unsigned int bkId);
        virtual bool updateBook(Book& book);
        virtual bool updateBook(Book& book, unsigned int bkId);
        virtual bool getBook(Book& book, unsigned int bkId);
        virtual list<Book> getAllBooks(const unsigned int order);
        void setSqlQryStmt(string qryStmt);
        void setSqlQryAllStmt(string qryAllStmt);
        void setSqlAddStmt(string addStmt);
        void setSqlUptStmt(string uptStmt);
        void setSqlDelStmt(string delStmt);
    
    private:
        MYSQL  mysqlDB;
        string sqlQryStmt;
        string sqlQryAllStmt;
        string sqlAddStmt;
        string sqlUptStmt;
        string sqlDelStmt;
    const string BOOKS_TBL;
    };
    


     

    1)  构造函数和析构函数的编写

    DAO的构造函数主要实现三个工作,首先读取配置文件中各项参数,如主机、用户名和密码等配置信息;其次,初始化并建立SQL连接;最后初始化基本的SQL语句;对应的析构函数则负责释放连接。如代码清单2-5所示。

    代码清单2-5

    using boost::property_tree::ptree;
    using boost::property_tree::xml_parser::xml_parser_error;
    using std::cerr;
    using std::endl;
    using std::stringstream;
    
    MysqlDBBookDAO::
    MysqlDBBookDAO(){}
    
    MysqlDBBookDAO::
    MysqlDBBookDAO(const string tbl, const string& configFileName):
    BOOKS_TBL(tbl) {
    
        // load configuration from xml
        ptree pt;
        try {
            read_xml(configFileName,  pt);
        }
        catch (xml_parser_error& err) {
            cerr << "Error, can't open config file "
                 << configFileName << endl;
            exit(EXIT_FAILURE);
        }
        const string host(pt.get<string>("mysqldb.host"));
        const string user(pt.get<string>("mysqldb.username"));
        const string pwd(pt.get<string>("mysqldb.password"));
        const string db(pt.get<string>("mysqldb.db"));
        const int port(pt.get("mysqldb.port", 0));
    
        mysql_init(&mysqlDB);
    
        if (!mysql_real_connect(
            &mysqlDB,
            host.c_str(),
            user.c_str(),
            pwd.c_str(),
            db.c_str(),
            port,
            NULL,
            0))
        {
            cerr << "exception: mysql connection failed" << endl;
            if (mysql_errno(&mysqlDB)) {
                cerr << mysql_error(&mysqlDB) << endl;
            }
            exit(EXIT_FAILURE);
        }
    
        stringstream sqlStrm;
        sqlStrm << "INSERT INTO `%s`(`book_id`, `isbn`, `title`, ";
        sqlStrm << "`author_first_name`, `author_last_name`, `num`, `price`) ";
        sqlStrm << "VALUES(%u, '%s', '%s', '%s', '%s', %u, %f) ";
        setSqlAddStmt(sqlStrm.str());
    
        sqlStrm.str("");
        sqlStrm << "DELETE FROM `%s` WHERE `book_id` = %u ";
        setSqlDelStmt(sqlStrm.str());
    
        sqlStrm.str("");
        sqlStrm << "UPDATE `%s` SET `isbn` = '%s', ";
        sqlStrm << "`title` = '%s', `author_first_name` = '%s', ";
        sqlStrm << "`author_last_name` = '%s', `num` = %u, ";
        sqlStrm << "`price` = %f WHERE `book_id` = %u ";
        setSqlUptStmt(sqlStrm.str());
    
        sqlStrm.str("");
        sqlStrm << "SELECT `book_id`, `isbn`, `title`, `author_first_name`, `author_last_name`, ";
        sqlStrm << "`num`, `price` FROM `%s` ";
        setSqlQryAllStmt(sqlStrm.str());
    
        sqlStrm << "WHERE `book_id` = %u ";
        setSqlQryStmt(sqlStrm.str());
    }
    MysqlDBBookDAO::
    ~MysqlDBBookDAO() {
        mysql_close(&mysqlDB);
    }
    


    1)  具体的数据访问函数

    代码清单2-6展示了具体的数据访问函数的实现。

    代码清单2-6

    bool MysqlDBBookDAO::
    saveBook(Book& book) {
        bool isOK = true;
    
        char * cStr = new char[1024];
    
        sprintf(cStr, sqlAddStmt.c_str(),
                BOOKS_TBL.c_str(),
                book.getBookID(),
                book.getISBN().c_str(),
                book.getTitle().c_str(),
                book.getAuthorFirstName().c_str(),
                book.getAuthorLastName().c_str(),
                book.getNum(),
                book.getPrice());
    
        int res = mysql_query(&mysqlDB, cStr);
    
        if (res) {
            cerr << mysql_error(&mysqlDB) << endl;
            isOK = false;
        }
    
        delete cStr;
        return isOK;
    }
    
    bool MysqlDBBookDAO::
    deleteBook(unsigned int bkId) {
        bool isOK = false;
    
        char * cStr = new char[1024];
    
        sprintf(cStr, sqlDelStmt.c_str(),
                BOOKS_TBL.c_str(), bkId);
    
        int res = mysql_query(&mysqlDB, cStr);
    
        if (res) {
            cerr << mysql_error(&mysqlDB) << endl;
            isOK = false;
        }
    
        delete cStr;
        return isOK;
    }
    
    bool MysqlDBBookDAO::
    updateBook(Book& book) {
        return updateBook(book, book.getBookID());
    }
    
    bool MysqlDBBookDAO::
    updateBook(Book& book, unsigned int bkId) {
        bool isOK = false;
    
        char * cStr = new char[1024];
    
        sprintf(cStr, sqlUptStmt.c_str(),
                BOOKS_TBL.c_str(),
                book.getISBN().c_str(),
                book.getTitle().c_str(),
                book.getAuthorFirstName().c_str(),
                book.getAuthorLastName().c_str(),
                book.getNum(), book.getPrice(),
                bkId);
    
        int res = mysql_query(&mysqlDB, cStr);
    
        if (res) {
            cerr << mysql_error(&mysqlDB) << endl;
            isOK = false;
        }
    
        delete cStr;
        return isOK;
    }
    
    bool MysqlDBBookDAO::
    getBook(Book& book, unsigned int bkId) {
        bool isOK = true;
        char * cStr = new char[1024];
        MYSQL_RES *resPtr = NULL;
        MYSQL_ROW sqlRow;
    
        sprintf(cStr, sqlQryStmt.c_str(),
                BOOKS_TBL.c_str(), bkId);
    
        int res = mysql_query(&mysqlDB, cStr);
    
        if (res) {
            cerr << mysql_error(&mysqlDB) << endl;
            isOK = false;
        } else {
            resPtr = mysql_use_result(&mysqlDB);
            if (resPtr) {
                while ((sqlRow = mysql_fetch_row(resPtr))) {
                    book.setBookID(atoi(sqlRow[0]));
                    book.setISBN(sqlRow[1]);
                    book.setTitle(sqlRow[2]);
                    book.setAuthorFirstName(sqlRow[3]);
                    book.setAuthorLastName(sqlRow[4]);
                    book.setNum(atoi(sqlRow[5]));
                    book.setPrice(atof(sqlRow[6]));
                }
                if (mysql_errno(&mysqlDB)) {
                    cerr << "Retrieve error: " << mysql_error(&mysqlDB) << endl;
                }
                mysql_free_result(resPtr);
            }
        }
    
        delete cStr;
        return isOK;
    }
    
    list<Book> MysqlDBBookDAO::
    getAllBooks(const unsigned int order) {
        MYSQL_RES *resPtr = NULL;
        MYSQL_ROW sqlRow;
        char * cStr = new char[1024];
    
        string qryAllStmt = sqlQryAllStmt;
        switch(order) {
            case BOOKID:
                qryAllStmt += "ORDER BY `book_id` ASC";
                break;
            case PRICE:
                qryAllStmt += "ORDER BY `price` ASC";
                break;
            case DEFAULT:
            default:
                break;
        }
    
        sprintf(cStr, qryAllStmt.c_str(),
                BOOKS_TBL.c_str());
    
        int res = mysql_query(&mysqlDB, cStr);
        list<Book> bookList;
        if (res) {
            cerr << mysql_error(&mysqlDB) << endl;
        } else {
            // fetch a row one at a time
            resPtr = mysql_use_result(&mysqlDB);
            if (resPtr) {
                while ((sqlRow = mysql_fetch_row(resPtr))) {
                    Book book;
                    book.setBookID(atoi(sqlRow[0]));
                    book.setISBN(sqlRow[1]);
                    book.setTitle(sqlRow[2]);
                    book.setAuthorFirstName(sqlRow[3]);
                    book.setAuthorLastName(sqlRow[4]);
                    book.setNum(atoi(sqlRow[5]));
                    book.setPrice(atof(sqlRow[6]));
                    bookList.push_back(book);
                }
                if (mysql_errno(&mysqlDB)) {
                    cerr << "Retrieve error: " << mysql_error(&mysqlDB) << endl;
                }
                mysql_free_result(resPtr);
            }
        }
    
        delete cStr;
        return bookList;
    }
    
    void MysqlDBBookDAO::
    setSqlQryStmt(string qryStmt) {
        if (!qryStmt.empty()) {
            sqlQryStmt = qryStmt;
        }
    }
    
    void MysqlDBBookDAO::
    setSqlQryAllStmt(string qryAllStmt) {
        if (!qryAllStmt.empty())  {
            sqlQryAllStmt = qryAllStmt;
        }
    }
    
    void MysqlDBBookDAO::
    setSqlAddStmt(string addStmt) {
        if (!addStmt.empty()) {
            sqlAddStmt = addStmt;
        }
    }
    
    void MysqlDBBookDAO::
    setSqlUptStmt(string uptStmt) {
        if (!uptStmt.empty()) {
            sqlUptStmt = uptStmt;
        }
    }
    
    void MysqlDBBookDAO::
    setSqlDelStmt(string delStmt) {
        if (!delStmt.empty()) {
            sqlDelStmt = delStmt;
        }
    }
    


    参考文献和网站

    1.       Fundamentals Of Rational Database Design

    1995年Paul Litwin为Access数据库写的一篇文献,虽然时间很久了但仍不失为一篇很好的入门教程,强烈推荐。

    2.       系统的数据建模教程

    http://www.databaseanswers.org/tutorials.htm

    国外一位DBA大牛的网站,有很多针对初学者的数据建模教程和现实世界的数据模型例子。

    DAO设计模式资料

    http://www.ibm.com/developerworks/cn/data/library/techarticles/dm-0502chenjunwei/

    IBM DevelopWorks一篇介绍各种数据库访问技术应用场景的文章,介绍各种更复杂的工业级解决方案。

    3.       DAO最佳实践

    http://best-practice-software-engineering.ifs.tuwien.ac.at/patterns/dao.html

    该网站介绍了大量的设计模式最佳实践,还有与之配套的使用Java语言编写的例子可供参考,是学习设计模式的好网站。

    4.       用Java语言编写的复杂DAO

    http://www.javaworld.com/javaworld/jw-03-2002/jw-0301-dao.html?page=1

    5.       百度百科对DTO的解释

    http://baike.baidu.com/view/160599.htm



     

     

    展开全文
  • h2数据库新手入门

    千次阅读 2018-04-28 14:23:52
    作为一枚使用h2数据库的新手,今天看到一篇文章比较适合新手用,特此收录原文出自:https://blog.csdn.net/fanpeizhong/article/details/73543260H2是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接...

    作为一枚使用h2数据库的新手,今天看到一篇文章比较适合新手用,特此收录

    原文出自:https://blog.csdn.net/fanpeizhong/article/details/73543260

    H2是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接嵌入到应用项目中。
      H2最大的用途在于可以同应用程序打包在一起发布,这样可以非常方便地存储少量结构化数据。
      它的另一个用途是用于单元测试。启动速度快,而且可以关闭持久化功能,每一个用例执行完随即还原到初始状态。
      H2的第三个用处是作为缓存,作为NoSQL的一个补充。当某些场景下数据模型必须为关系型,可以拿它当Memcached使,作为后端MySQL/Oracle的一个缓冲层,缓存一些不经常变化但需要频繁访问的数据,比如字典表、权限表。不过这样系统架构就会比较复杂了。

    一、产品优势   
    • 纯Java编写,不受平台的限制;
    • 只有一个jar文件,适合作为嵌入式数据库使用;
    • h2提供了一个十分方便的web控制台用于操作和管理数据库内容;
    • 功能完整,支持标准SQL和JDBC。麻雀虽小五脏俱全;
    • 支持内嵌模式、服务器模式和集群。

    二、下载和安装
    (一)下载
      H2数据库下载地址: http://www.h2database.com/html/download.html


      聪明如你肯定会选第二个。Windows、Linux下都可以直接解压缩就用,符合永远中二中年开发者的使用习惯。
    (二)解压缩后的目录结构:
      h2
      |---bin
      |    |---h2-1.1.116.jar   //H2数据库的jar包(驱动也在里面)
      |    |---h2.bat              //Windows控制台启动脚本
      |    |---h2.sh                  //Linux控制台启动脚本
      |    |---h2w.bat              //Windows控制台启动脚本(不带黑屏窗口)
      |---docs                       //H2数据库的帮助文档(内有H2数据库的使用手册)
      |---service //通过wrapper包装成服务。
      |---src //H2数据库的源代码
      |---build.bat //windows构建脚本
      |---build.sh //linux构建脚本

      此时就算“安装”完成了。

    三、运行模式与运行方式
    (一)运行模式
      H2有三种运行模式。
      1、内嵌模式(Embedded Mode)
      内嵌模式下,应用和数据库同在一个JVM中,通过JDBC进行连接。 可持久化,但同时只能一个客户端连接。内嵌模式性能会比较好。

      2、服务器模式(Server Mode)
      使用服务器模式和内嵌模式一样,只不过它可以跑在另一个进程里。

      3、 混合模式
      第一个应用以内嵌模式启动它,对于后面的应用来说它是服务器模式跑着的。混合模式是内嵌模式和服务器模式的组合。第一个应用通过内嵌模式与数据库建立连接,同时也作为一个服务器启动,于是另外的应用(运行在不同的进程或是虚拟机上)可以同时访问同样的数据。第一个应用的本地连接与嵌入式模式的连接性能一样的快,而其它连接理论上会略慢。 

    (二)运行方式
      开发中肯定是Server Mode方便,因为需要用工具管理数据。所以 进入H2的bin目录。

      如果你在Win环境可以运行h2.bat或h2w.bat。区别只是后者是后台静默运行。

      如果你在Linux环境,可运行./h2.sh文件欢快地跑起来数据库服务。但其实不建议酱紫,因为这样有诸多不便。可如下修改:
    1. 复制h2.sh为h2_server.sh文件;

    1. 编辑h2_server.sh,如下#!/bin/shdir=$(dirname"$0")java -cp "$dir/h2-1.3.176.jar:$H2DRIVERS:$CLASSPATH" org.h2.tools.Server -tcpAllowOthers -webAllowOthers -webPort 8082"$@"
    2. 说明: 
      org.h2.tools.Server: 以服务器模式启动 
      -tcpAllowOthers: 允许远程机器通过TCP方式访问 
      -webAllowOthers: 允许远程机器通过浏览器访问 
      -webPort 8082: 默认的访问端口(8082为未被占用的端口,如果此端口已经被其他端口占用,则改为其他端口)
    1. 具体的运行方式
      ①chmod修改文件权限;
      ②输入nohup ./h2_server.sh &回车。这样可以后台运行;

    四、远程管理
    1. 通过远程浏览器来访问h2 
      访问地址:http://服务器ip:8082/ ,出现如下页面:

      2.路径的配置
      jdbc:h2:tcp://localhost//usr/h2/data/rlib 是H2的路径。tcp代表使用tcp方式访问。localhost/是IP。因为例子是在Linux下,数据库的文件路径是“/usr/h2/data/rlib”,所以localhost/后面还有个/。详细的URL设置可见本文附录。(聪明如你,可能会问为什么既然H2远程部署在Linux下但使用浏览器访问IP还填写localhost?就不告诉你)
      User name : sa是h2默认的用户,密码可空。但作为永远中二随性的中年开发者,好歹设置下密码,尤其当你的H2部署在公网时。不然会被无聊人把数据删到汗裤都不剩。

      3.点击如图Test connect按钮测试连接。此时如果数据库文件本身不存在则会自动创建。数据库文件自动生成到/usr/h2/data/目录下,名为rlib.mv.db。点击Connect,进入管理终端。

      H2的管理终端做得很不错的。按Ctrl+Enter执行输入区的SQL,按Shift+Enter执行当前选中的SQL。

    五、数据备份恢复
      不能备份和导入数据的数据库是跛脚的。可通过自带的CSVWRITE方法导出为csv格式文件,也可通过CSVREAD 导入数据。
      (一)导出函数CSVWRITE

      例子:CALL CSVWRITE('test2.csv', 'SELECT * FROM TEST', 'charset=UTF-8 fieldSeparator=|');
       注意:导出时就算加上编码,导出后的文件用VIM、Editplus查看是正常,但用Excel查看也仍然会是乱码的。需要用Editplus另存为Unicode,就好了。
      (二)导入函数CSVWRITE
      语法: CSVREAD( fileNameString [, columnsString [, csvOptions ] ] )
      例子①: 导入数据: INSERT INTO TEST ( SELECT * FROM CSVREAD('d:/test.csv ')) ;
      例子②: 导入结构及数据, 根据csv文件创建h2数据表。
      //csv文件数据创建test表
      CREATE TABLE TEST AS SELECT * FROM CS VREAD('d:/test.csv ');
      //创建test表,csv文件相应的列插入到test表相应的字段
      CREATE TABLE TEST(ID INT PRIMARY KEY, NAME VARCHAR(255)) AS SELECT * FROM CSVREAD('d:/test.csv ');
      (三)csvOptions

    六、应用程序开发
      终于到了开发使用环节了。H2数据库的开发非常简单,和MySQL等没有太大区别。
      (一)加入Maven依赖
    < dependency >
    < groupId > com.h2database </ groupId >
    < artifactId > h2 </ artifactId >
    < version > 1.4.195 </ version >
    </ dependency >
      (二)创建db.properties
    driverClassName = org.h2.Driver
    #此处的写法是使用嵌入模式链接H2库,紧接着那行是使用Server Mode用tcp连接。区别一个是前者性能更好,后者可同时多个客户端连接
    url = jdbc:h2:D:/test
    #url=jdbc:h2:tcp://1localhost//usr/h2/data/rlib
    username = sa
    password =

    PS:在使用嵌入模式链接H2库时,使用管理页面连接会报错如下:

      (三)使用如上db.properties即可使用H2数据库进行开发。具体的数据库操作等不属于H2范畴,可自行参考其它资料。


    附录:H2数据库不同模式连接字串
     URL Format and Examples
    Embedded (local) connectionjdbc:h2:[file:][<path>]<databaseName>
    jdbc:h2:~/test
    jdbc:h2:file:/data/sample
    jdbc:h2:file:C:/data/sample (Windows only)
    In-memory (private)jdbc:h2:mem:
    In-memory (named)jdbc:h2:mem:<databaseName>
    jdbc:h2:mem:test_mem
    Server mode (remote connections) using TCP/IPjdbc:h2:tcp://<server>[:<port>]/[<path>]<databaseName>
    jdbc:h2:tcp://localhost/~/test
    jdbc:h2:tcp://dbserv:8084/~/sample
    jdbc:h2:tcp://localhost/mem:test
    Server mode (remote connections) using TLSjdbc:h2:ssl://<server>[:<port>]/<databaseName>
    jdbc:h2:ssl://localhost:8085/~/sample;
    Using encrypted filesjdbc:h2:<url>;CIPHER=AES
    jdbc:h2:ssl://localhost/~/test;CIPHER=AES
    jdbc:h2:file:~/secure;CIPHER=AES
    File locking methodsjdbc:h2:<url>;FILE_LOCK={FILE|SOCKET|NO}
    jdbc:h2:file:~/private;CIPHER=AES;FILE_LOCK=SOCKET
    Only open if it already existsjdbc:h2:<url>;IFEXISTS=TRUE
    jdbc:h2:file:~/sample;IFEXISTS=TRUE
    Don't close the database when the VM exitsjdbc:h2:<url>;DB_CLOSE_ON_EXIT=FALSE
    Execute SQL on connectionjdbc:h2:<url>;INIT=RUNSCRIPT FROM '~/create.sql'
    jdbc:h2:file:~/sample;INIT=RUNSCRIPT FROM '~/create.sql'\;RUNSCRIPT FROM '~/populate.sql'
    User name and/or passwordjdbc:h2:<url>[;USER=<username>][;PASSWORD=<value>]
    jdbc:h2:file:~/sample;USER=sa;PASSWORD=123
    Debug trace settingsjdbc:h2:<url>;TRACE_LEVEL_FILE=<level 0..3>
    jdbc:h2:file:~/sample;TRACE_LEVEL_FILE=3
    Ignore unknown settingsjdbc:h2:<url>;IGNORE_UNKNOWN_SETTINGS=TRUE
    Custom file access modejdbc:h2:<url>;ACCESS_MODE_DATA=rws
    Database in a zip filejdbc:h2:zip:<zipFileName>!/<databaseName>
    jdbc:h2:zip:~/db.zip!/test
    Compatibility modejdbc:h2:<url>;MODE=<databaseType>
    jdbc:h2:~/test;MODE=MYSQL
    Auto-reconnectjdbc:h2:<url>;AUTO_RECONNECT=TRUE
    jdbc:h2:tcp://localhost/~/test;AUTO_RECONNECT=TRUE
    Automatic mixed modejdbc:h2:<url>;AUTO_SERVER=TRUE
    jdbc:h2:~/test;AUTO_SERVER=TRUE
    Page sizejdbc:h2:<url>;PAGE_SIZE=512
    Changing other settingsjdbc:h2:<url>;<setting>=<value>[;<setting>=<value>...]
    jdbc:h2:file:~/sample;TRACE_LEVEL_SYSTEM_OUT=3

    展开全文
  • Greenplum分布式数据库开发入门到精通(架构、部署、管理、开发和调优) 课程分类:Hadoop 适合人群:初级 课时数量:41课时 用到技术:GP、MapReduce编程、装载和卸载数据 涉及项目:角色权限及客户端认证管理 ...
  • 数据库 Neo4j 入门

    千次阅读 2013-03-05 19:18:19
     在众多不同的数据模型里,关系数据模型自80年代就处于统治地位,而且有不少实现,如Oracle、MySQL和MSSQL,它们也被称为关系数据库管理系统(RDBMS)。然而,最近随着关系数据库使用案例的不断增加,一些问题也...
  • 数据库入门概略

    2011-11-08 19:36:38
    前段时间由于wince图片浏览器需要一个数据库去存储原图和缩略图的路径等信息,就...数据库理论: 主要熟悉E-R图,关系型数据库,常用SQL语句 E-R图可用于软件设计文档里表示概念数据模型,E-R图元素:实体、属性、联系
  • 数据库 设计经典入门

    2009-08-11 09:34:34
    数据库设计经典入门,非常适合初学者,包括了数据库设计过程,规范化理论,设计模式,设计经验和技巧等等
  • 本教程的作者具有多年数据库维护与开发工作经验,在本书编写的过程中秉承理论学习与实际开发相结合的原则,力求实现所有技术点和经典案例的完美搭配,帮助RDS数据库初学者轻松入门,并迅速达到熟练程度。
  • 数据库入门到实践

    2012-07-12 16:54:40
    针对新手入门的很好的指导资料 第一章:数据库系统导论; 第二章:面向对象数据库; 第3章 关系数据库标准语言SQL 第四章 关系系统及查询优化 第5章 关系数据理论 第六章 数据库设计 第七章 数据库恢复技术 第八章 ...
  • H2数据库入门

    万次阅读 2019-06-05 10:08:49
      1、H2是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接嵌入到应用项目中。   H2最大的用途在于可以同应用程序打包在一起发布,这样可以非常方便地存储少量结构化数据。   它的另一个用途是...
  • 本书没有涉及理论,而是从实践出发,由浅入深地讲解了广大读者所必需的SQL 知识,适用于各种主流数据库。实例丰富,便于查阅。 本书涉及不同平台上数据的排序、过滤和分组,以及表、视图、联结、子查询、游标、存储...
  • 数据库设计入门经典》之前言

    千次阅读 2008-02-27 11:30:00
    这个学期开始学习数据库设计,手头上有一本参考书《数据库设计入门经典》。在课下自己看这本书,感觉挺有用的,现在想很自己学习的心德和感想写下来,为以后的学习做点积累。。。。 首先,先介绍一下这本书的作者与...
  • 本书没有涉及理论,而是从实践出发,由浅入深地讲解了广大读者所必需的SQL 知识,适用于各种主流数据库。实例丰富,便于查阅。   本书涉及不同平台上数据的排序、过滤和分组,以及表、视图、联结、子查询、...
  • MongoDB 是NoSQL 的一种,面向文档的数据库, 介于传统的结构化数据库(关系型数据库)与非结构化数据库(文件存储)之间的一种,它的数据结构非常松散,也非常... 在github 上找到了这个入门文档,转载在博客上,方便自己
  • MySQL数据库应用快速入门培训课程

    万人学习 2019-12-24 22:11:12
    快速掌握Mysql应用,理论为辅,实践为主,本课程属于精简版,目的是让学员快速上手MySQL 本课程是mysql的入门课程,linux  和 windows 下面两种方式对mysql  进行安装,通过sql语句创建数据库,创建数据表...
  • Oracle数据库入门心得

    千次阅读 2014-01-02 15:20:57
    Oracle数据库入门心得 Oracle的体系太庞大了,对于初学者来说,难免会有些无从下手的感觉,什么都想学,结果什么都学不好,所以把学习经验共享一下,希望让刚刚入门的人对oracle有一个总体的认识,少走一些弯路。...
  • 01-老男孩运维DBA课程开班02-数据库概念介绍从架构上解决数据库的瓶颈说明了一个道理,有问题不要自己抗,要团队精神,数据库有问题了不要自己扛,让前端memcache扛,把数据静态化,让web服务器扛03-数据库种类介绍...
  • 我写的不一定对,但是尽量都写了分析,错的请指正。 搜题直接 Ctrl+F 就OK ... 对应数据库的升级、外模式包括(子模式 用户模式) 用来描述用户看到或者使用那部分的数据的逻辑结构,用户根据外模...
  • 上一次写了一点第二章的笔记,强调了在做数据库模型的设计时要注意“人”的作用,这一次,来说点正题。第三章的主题目是:数据库建模构件块,看过了以后觉得有些还是在讲数据库的概念性东西,不过,就算是学过了也...
  • 达梦数据库入门之小问题汇总20190915 曾经在运营商集成子公司呆了蛮多年,从业多年几乎一直专攻视频监控、网络...
  • Oracle数据库应用与开发第01章[Oracle入门]理论课;课程目标;目标 ; Oracle 数据库简介 2-1; Oracle 数据库简介 2-2;Oracle 9i 体系结构;Oracle 数据库;Oracle 物理组件;Oracle 实例 ;Oracle 实例内存结构;系统全局区...
  • mysql数据库入门(1)--各种数据库介绍

    千次阅读 2016-11-04 15:33:35
    各种数据库介绍数据库介绍1. 什么是数据库    简单说存放数据的仓库,这个仓库按照一定的数据结构<数据结构是指数据的组织形 式或数据之间的联系>来组织、存储的,我们可以通过数据库提供的多种方法来管理...
  • 1、创建数据库 1.1、理论: 1.2、实践 2、修改删除数据库 2.1、理论: 2.2、实践 3、分离附加数据库 3.1、
  • 带你发现新大陆!什么是图数据库以及简单入门

    万次阅读 多人点赞 2018-01-17 21:16:24
    一、关系型数据库的不适性 在众多不同的数据模型里,关系数据模型自20世纪80年代就处于统治地位,而且出现了不少巨头,如Oracle、MySQL,它们也被称为:关系数据库管理系统(RDBMS)。然而,随着关系数据库使用范围...
  • 数据库入门基本知识(一)

    千次阅读 2018-05-16 19:27:28
    安装mysql数据库 安装oracle 数据库 2.0 sql语言 2.1 sql语言的特点 综合统一 SQL集数据的定义、操作、控制与一体,语言风格统一,可以的独立完成数据库生命周期的所有活动 高度非过程化 不管怎么做,你...
  • 对于数据库初学者来说,数据库是一门博大精深的理论,下面浅尝辄止的介绍一些跟数据库相关的知识,共数据库初级爱好者分享~ 1.什么是数据库学习 侠义讲:存储数据的仓库 广义讲:可以对数据进行存储管理的软件 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,462
精华内容 16,584
关键字:

数据库理论入门