zoukankan      html  css  js  c++  java
  • 数据库

    一、SQL语句

    • 删除数据库:drop database school;
    • 查看表结构:describe student; / desc student; / show create table student
    • 主键:单字段主键,多字段主键
    • 外键:表A中的id是外键,表B中的id是主键,则表B为父表,表A为子表。设置表外键的作用在于建立与父表的联系,比如表B中id为123的学生删除后,表A中id为123的记录也随着消失。
    • mysql> create table student3(
      -> id int primary key,
      -> course_id int,
      -> teacher varchar(20),
      -> constraint fk foreign key(id,course_id)
      -> references student2(id,course_id)
      -> );
      Query OK, 0 rows affected (0.12 sec)

      这里创建student3表,constraint后面的fk是外键别名,foreign key也就是设置外键的字段,references后的内容表示父表,和父表中的主键。需要注意的是,父表中的主键不能为空,并且主键和外键的数据类型要一致。

    • 删除表用drop,修改表用alter, 删除记录用delete
    • 查询:

    where 后面可以跟in,not in, between and, not between and, like, not like, null, regexp...

    其他条件:and, or, destinct, order by, group by, limit

    函数:count(), sum(), avg(), max(), min(), concat()

    • mysql 数据类型 http://www.cnblogs.com/nerxious/archive/2012/12/31/2840226.html
    • jdbc http://www.cnblogs.com/nerxious/archive/2012/12/31/2839963.html
    • 触发器:
      mysql> CREATE TRIGGER trig1 AFTER INSERT
      -> ON work FOR EACH ROW
      -> INSERT INTO time VALUES(NOW());

      上面创建了一个名为trig1的触发器,一旦在work中有插入动作,就会自动往time表里插入当前时间。

    1、左外连接,右外连接

      左:从左表读出一条,选出所有与on匹配的右表纪录(n条)进行连接,形成n条纪录(包括重复的行),如果右边没有与on条件匹配的表,那连接的字段都是null.然后继续读下一条。

      如:select id, name, action from user u left join user_action a on u.id = a.user_id   

      找出所有在左表而不在右表的记录:

    select id, name, action from user as u left join user_action a on u.id = a.user_id where a.user_id is NULL 

      如果连接的两个表连接条件的两个列具有相同的名字的话可以使用USING:select ... from table1 left join table2 using id

    2、distinct 和 group by

    # distinct测试
    select * from student;         
    a    5
    a    5
    c    0
    
    select distinct name,age from student;
    a    5
    c    0
    
    select * from student;
    c    2
    c    5
    
    select distinct name,age from student;
    返回如下,说明distinct后面有多于一列的字段时,只有每列的值完全相同才过滤
    c    2
    c    5
    
    
    #group by 测试
    select * from student;
    name age height
    c    2   123
    c    2   456
    b    20  222
    
    按name,age 两列相同分组
    select name,age,sum(height) from student group by name,age;
    b    20    222
    c    2    579
    
    group by 后面加having
    select name,age,sum(height) as n from student group by name,age having n > 500;
    c    2    579
    
    group by后面limit
    select songname, sengerid, count(sengerid) as n from t_song group by songname, sengerid having n > 1 ORDER BY n DESC, songid ASC limit 5;
    未知       8738    40
    共同渡过    1432    24
    风继续吹    1432    23
    倩女幽魂    1432    23
    无心睡眠    1432    23
    
    
    delimiter ||  #改变mysql命令结束符为|| 
    
    # 测试distinct 和 group by
    http://blog.51yip.com/mysql/1105.html

    3、mysql索引

    索引分类
    1.普通索引:不附加任何限制条件,可创建在任何数据类型中
    2.唯一性索引:使用unique参数可以设置索引为唯一性索引,在创建索引时,限制该索引的值必须唯一,主键就是一种唯一性索引
    3.全文索引:使用fulltext参数可以设置索引为全文索引。全文索引只能创建在char、varchar或text类型的字段上。查询数据量较大的字符串类型字段时,效果明显。但只有MyISAM存储引擎支持全文检索
    4.单列索引:在表中单个字段上创建的索引,单列索引可以是任何类型,只要保证索引只对应一个一个字段
    5.多列索引:在表中多个字段上创建的索引,该索引指向创建时对应的多个字段
    6.空间索引:使用spatial参数可以设置索引为空间索引,空间索引只能建立在空间数据类型上比如geometry,并且不能为空,目前只有MyISAM存储引擎支持

    索引关键字的选取原则
    1、表的某个字段值得离散度越高,该字段越适合选作索引的关键字。主键字段以及唯一性约束字段适合选作索引的关键字,原因就是这些字段的值非常离散。尤其是在主键字段创建索引时,cardinality(基数,集的势)的值就等于该表的行数。MySQL在处理主键约束以及唯一性约束时,考虑周全。数据库用户创建主键约束的同时,MySQL自动创建主索引(primary index),且索引名称为Primary;数据库用户创建唯一性索引时,MySQL自动创建唯一性索引(unique index),默认情况下,索引名为唯一性索引的字段名。
    2、占用存储空间少的字段更适合选作索引的关键字。例如,与字符串相比,整数字段占用的存储空间较少,因此,较为适合选作索引关键字。
    3、存储空间固定的字段更适合选作索引的关键字。与text类型的字段相比,char类型的字段较为适合选作索引关键字。
    4、Where子句中经常使用的字段应该创建索引,分组字段或者排序字段应该创建索引,两个表的连接字段应该创建索引。
    5、更新频繁的字段不适合创建索引,不会出现在where子句中的字段不应该创建索引。
    6、最左前缀原则。
    7、尽量使用前缀索引。
         引入索引的目的就是提高数据的检查效率,因此索引关键字的选择与select语句息息相关。这句话有两个含义:一是,select语句的设计可以决定索引的设计;索引的设计也同样影响着select语句的设计。例如原则1与原则2,可以影响select语句的设计;而select语句中的where子句、group by子句又可以影响索引的设计。两个表的连接字段应该创建索引,外键约束一经创建,MySQL会自动地创建与外键相对应的索引,这是由于外键字段通常是两个表的连接字段。
      复合索引还有一个优点,它通过被称为“最左前缀”(leftmost prefixing)的概念体现出来的。假设向一个表的多个字段(例如fristname、lastname、address)创建复合索引(索引名为fname_lname_address).当where查询条件是以下各种字段的组合是,MySQL将使用fname_lname_address索引。其他情况将无法使用fname_lname_address索引。可以理解:一个复合索引(firstname、lastname、address)等效于(firstname,llastname,age)、(firstname,lastname)以及(firstname)三个索引。基于最做前缀原则,应尽量避免创建重复的索引,例如,创建了fname_lname_address索引后,就无需再first_name子段上单独创建一个索引。
      如果数据库表的存储引擎是MyISAM,那么创建主键的约束的同时,MySQL会自动创建主键索引。如果数据库表的存储引擎是InnoDB,那么创建主键约束的同时,MySQL会自动创建聚簇索引。
      MySQL还支持全文索引(fulltext),当查询数据量大的字符串信息时,使用全文索引可以大幅提升字符串的检索效率。需要注意的是,全文索引只能创建在char、varchar或者text字符串类型的字段上,且全文索引不支持前缀索引。

    二、数据库系统

    1、事务并发和事务隔离

    • 数据库系统提供了四种事务隔离级别供用户选择:

    A.Serializable(串行化):一个事务在执行过程中完全看不到其他事务对数据库所做的更新(事务执行的时候不允许别的事务并发执行。事务串行化执行,事务只能一个接着一个地执行,而不能并发执行)。
    B.Repeatable Read(可重复读):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,但是不能看到其他其他事务对已有记录的更新。
    C.Read Commited(读已提交数据):一个事务在执行过程中可以看到其他事务已经提交的新插入的记录,而且能看到其他事务已经提交的对已有记录的更新。
    D.Read Uncommitted(读未提交数据):一个事务在执行过程中可以看到其他事务没有提交的新插入的记录,而且能看到其他事务没有提交的对已有记录的更新。

    • 并发问题可归纳为以下几类:

    A.丢失更新:撤销一个事务时,把其他事务已提交的更新数据覆盖(A和B事务并发执行,A事务执行更新后,提交;B事务在A事务更新后,B事务结束前也做了对该行数据的更新操作,然后回滚,则两次更新操作都丢失了)。
    B.脏读:一个事务读到另一个事务未提交的更新数据(A和B事务并发执行,B事务执行更新后,A事务查询B事务没有提交的数据,B事务回滚,则A事务得到的数据不是数据库中的真实数据。也就是脏数据,即和数据库中不一致的数据)。
    C.不可重复读:一个事务读到另一个事务已提交的更新数据(A和B事务并发执行,A事务查询数据,然后B事务更新该数据,A再次查询该数据时,发现该数据变化了)。
    D. 覆盖更新:这是不可重复读中的特例,一个事务覆盖另一个事务已提交的更新数据(即A事务更新数据,然后B事务更新该数据,A事务查询发现自己更新的数据变了)。
    E.虚读(幻读):一个事务读到另一个事务已提交的新插入的数据(A和B事务并发执行,A事务查询数据,B事务插入或者删除数据,A事务再次查询发现结果集中有以前没有的数据或者以前有的数据消失了)。

    • 事务控制语句:

    start transction | begin : 显示的开启一个事务
    commit (commit work)
    rollback
    在存储过程中,只能用start transaction

     2、事务的特性ACID

    事务(Transaction)是并发控制的基本单位。所谓事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转帐工作:从一个帐号扣款并使另一个帐号增款,这两个操作要么都执行,要么都不执行。

      数据库事务必须具备ACID特性,ACID是Atomic(原子性)、Consistency(一致性)、Isolation(隔离性)和Durability(持久性)的英文缩写。

      原子性:指整个数据库事务是不可分割的工作单位。只有使据库中所有的操作执行成功,才算整个事务成功;事务中任何一个SQL语句执行失败,那么已经执行成功的SQL语句也必须撤销,数据库状态应该退回到执行事务前的状态。

      一致性:指数据库事务不能破坏关系数据的完整性以及业务逻辑上的一致性。例如对银行转帐事务,不管事务成功还是失败,应该保证事务结束后ACCOUNTS表中Tom和Jack的存款总额为2000元。

      隔离性:指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。由并发事务所做的修改必须与任何其他并发事务所做的修改隔离。事务查看数据更新时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

      持久性:指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

      事务的(ACID)特性是由关系数据库管理系统(RDBMS,数据库系统)来实现的。数据库管理系统采用日志来保证事务的原子性、一致性和持久性。日志记录了事务对数据库所做的更新,如果某个事务在执行过程中发生错误,就可以根据日志,撤销事务对数据库已做的更新,使数据库退回到执行事务前的初始状态。数据库管理系统采用锁机制来实现事务的隔离性。当多个事务同时更新数据库中相同的数据时,只允许持有锁的事务能更新该数据,其他事务必须等待,直到前一个事务释放了锁,其他事务才有机会更新该数据。

     3、MyISAM和InnoDB

    MyISAM是MySQL的默认存储引擎,基于传统的ISAM类型,支持全文搜索,但不是事务安全的,而且不支持外键。每张MyISAM表存放在三个文件中:frm 文件存放表格定义;数据文件是MYD (MYData);索引文件是MYI (MYIndex)。

    InnoDB是事务型引擎,支持回滚、崩溃恢复能力、多版本并发控制、ACID事务,支持行级锁定(InnoDB表的行锁不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,如like操作时的SQL语句),以及提供与Oracle类型一致的不加锁读取方式。InnoDB存储它的表和索引在一个表空间中,表空间可以包含数个文件。

    主要区别:
    MyISAM是非事务安全型的,而InnoDB是事务安全型的。
    MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
    MyISAM支持全文类型索引,而InnoDB不支持全文索引。
    MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。
    MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。
    InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。
    InnoDB中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。但是,当count(*)语句包含 where条件时,两种表的操作是一样的。
    Innodb的数据组织就是按照主键建成的一个B+树,如果没有显示的定义主键,那么innodb会选取一个not null unique key,作为主键,如果还是没有,那么innodb会创建一个6字节的主键,主键索引到页不是具体的行位置

    应用:
    先考虑这些问题:
    你的数据库有外键吗?
    你需要事务支持吗?
    你需要全文索引吗?
    你经常使用什么样的查询模式?
    你的数据有多大?

    如果你需要事务处理或是外键,那么InnoDB 可能是比较好的方式。如果你需要全文索引,那么通常来说MyISAM是好的选择,因为这是系统内建的。
    COUNT() 在 MyISAM 表中会非常快,而在InnoDB 表下可能会很痛苦。而主键查询则在InnoDB下会相当相当的快,但需要小心的是如果我们的主键太长了也会导致性能问题。大批的inserts语句在MyISAM下会快一些,但是updates 在InnoDB 下会更快一些——尤其在并发量大的时候。

      

  • 相关阅读:
    堆表、AO表 行存列存
    PostgreSQL/PPAS CPU使用率高的排查及解决办法【转】
    GP 锁表查询
    gp 日常使用脚本
    常用gp_toolkit监控语句
    DG 参数详解
    Flask 中路由系统
    实例化Flask的参数 及 对app的配置
    Flask 中内置的 Session
    Flask中request参数
  • 原文地址:https://www.cnblogs.com/hesier/p/5844714.html
Copyright © 2011-2022 走看看