精华内容
下载资源
问答
  • 多表连接分为:内连接和外连接,结合示例说明它们之间的差别和应用 Employee表  eNo eName Age depNo 1 张小 27 1 2 黄二 20 ...

    连接查询

    多表连接分为:内连接和外连接,结合示例说明它们之间的差别和应用

    Employee表                                                  

    eNo

    eName

    Age

    depNo

    1

    张小

    27

    1

    2

    黄二

    20

    1

    3

    卫三

    33

    2

    4

    齐七

    27

     

    Department

    dNo

    dName

    1

    技术

    2

    人事

    3

    后勤

    4

    销售

     

    1.内连接--inner join 

    查询员工编号、姓名、年龄和所在部门名称,内连接查询:

    Select e.eNo,e.eName,e.age,d.dName 

         From employee as e (inner) join department as d 

         On e.depNo=d.dNo

    employeedepartment之间通过键连接,employee中为depNodepartment中为dNo,语句中在on后面指出

    查询结果为:

    eNo

    eName

    Age

    dName

    1

    张小

    27

    技术

    2

    黄二

    20

    技术

    3

    卫三

    33

    人事

    内连接又称为等值连接,只返回由键连接符合条件的结果

    2.外连接

    内连接查询只能获得两表中具有‘共同’部分的结果,有时候我们需要employee中所有的数据或者department中所有的数据,这可以使用外连接实现。外连接包括左外连接、右外连接和全连接,其作用不同。

    1)左外连接--left out join以左表为基准表,返回左表的所有数据和右表中符合条件的数据,如果右表中没有对应的值则为null

    左外连接查询:

    Select e.eNo,e.eName,e.age,d.dName

    From employee e left out) join department d

    On e.depNo=d.dNo

    查询结果为:

    eNo

    eName

    Age

    dName

    1

    张小

    27

    技术

    2

    黄二

    20

    技术

    3

    卫三

    33

    人事

    4

    齐七

    27

    null

     

    (2)右外连接--right out join 以右表为基准表,结果返回右表所有数据和左表符合条件的数据,如果左表中没有对应的值则返回null

    右外连接查询:

    Select e.eNo,e.eName,e.age,d.dName

    From employee e right (out) join department d

    On e.depNo = d.dNo

    查询结果:

    eNo

    eName

    Age

    depNo

    1

    张小

    27

    技术

    2

    黄二

    20

    技术

    3

    卫三

    33

    人事

    null

    null

    null

    后勤

    null

    null

    null

    销售

     

    (3)全连接--full join 查询结果返回两个表中所有数据

    全连接查询:

    Select e.eNo,e.eName,e.age,d.Name

    From deployee e full join department d

    On e.depNo = d.dNo

    查询结果:

    eNo

    eName

    Age

    depNo

    1

    张小

    27

    技术

    2

    黄二

    20

    技术

    3

    卫三

    33

    人事

    4

    齐七

    27

    null

    null

    null

    null

    后勤

    null

    null

    null

    销售

     

       

    展开全文
  • 非常少用join,这次学学,并备忘两篇文章! ...连接查询 通过连接运算符能够实现查询。...在关系数据库管理系统中,建立时各数据之间的关系不必确定,常把一个实体的全部信息存放在一个中。当检...

    非常少用join,这次学学,并备忘两篇文章!

    转自:http://hcx-2008.javaeye.com/blog/285661

    连接查询

    通过连接运算符能够实现多个表查询。连接是关系数据库模型的主要特点,也是它差别于其他类型数据库管理系统的一个标志。

    在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的全部信息存放在一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带来非常大的灵活性,他们能够在不论什么时候添加新的数据类型。为不同实体创建新的表,尔后通过连接进行查询。

    连接能够在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这个方法。

    SQL-92标准所定义的FROM子句的连接语法格式为:

    FROM join_table join_type join_table

    [ON (join_condition)]

    当中join_table指出參与连接操作的表名,连接能够对同一个表操作,也能够对多表操作,对同一个表操作的连接又称做自连接。

    join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比較运算符进行表间某(些)列数据的比較操作,并列出这些表中与连接条件相匹配的数据行。依据所使用的比較方式不同,内连接又分为等值连接、自然连接和不等连接三种。

    外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不仅仅列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中全部符合搜索条件的数据行。

    交叉连接(CROSS JOIN)沒有WHERE 子句,它返回连接表中全部数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

    连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比較运算符、逻辑运算符等构成。

    不管哪种连接都不能对text、ntext和image数据类型列进行直接连接,但能够对这三种列进行间接连接。比如:

    SELECT p1.pub_id,p2.pub_id,p1.pr_info

    FROM pub_info AS p1 INNER JOIN pub_info AS p2

    ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

    (一)内连接

    内连接查询操作列出与连接条件匹配的数据行,它使用比較运算符比較被连接列的列值。内连接分三种:

    1、等值连接:在连接条件中使用等于号(=)运算符比較被连接列的列值,其查询结果中列出被连接表中的全部列,包含当中的反复列。

    2、不等连接: 在连接条件使用除等于运算符以外的其他比較运算符比較被连接的列的列值。这些运算符包含>、>=、<=、<、!>、!<和<>。

    3、自然连接:在连接条件中使用等于(=)运算符比較被连接列的列值,但它使用选择列表指出查询结果集合中所包含的列,并删除连接表中的反复列。

    例,以下使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:

    SELECT *

    FROM authors AS a INNER JOIN publishers AS p

    ON a.city=p.city

    又如使用自然连接,在选择列表中删除authors 和publishers 表中反复列(city和state):

    SELECT a.*,p.pub_id,p.pub_name,p.country

    FROM authors AS a INNER JOIN publishers AS p

    ON a.city=p.city

    (二)外连接

    内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件的行。而採用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,并且还包含左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的全部数据行。

    如以下使用左外连接将论坛内容和作者信息连接起来:

    SELECT a.,b. FROM luntan LEFT JOIN usertable as b

    ON a.username=b.username

    以下使用全外连接将city表中的全部作者以及user表中的全部作者,以及他们所在的城市:

    SELECT a.,b.

    FROM city as a FULL OUTER JOIN user as b

    ON a.username=b.username

    (三)交叉连接

    交叉连接不带WHERE 子句,它返回被连接的两个表全部数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

    例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等

    于6*8=48行。

    SELECT type,pub_name

    FROM titles CROSS JOIN publishers

    ORDER BY type

    转自:http://topic.csdn.net/t/20060809/09/4936637.html

    12 楼aw511(点点星灯)回复于 2006-08-22 09:13:42 得分 0 --查询分析器中运行:

    --建表table1,table2:
    create table table1(id int,name varchar(10))
    create table table2(id int,score int)
    insert into table1 select 1,'lee'
    insert into table1 select 2,'zhang'
    insert into table1 select 4,'wang'
    insert into table2 select 1,90
    insert into table2 select 2,100
    insert into table2 select 3,70

    如表

    table1|table2|

    idname|idscore|
    1lee|190|
    2zhang|2100|

    4wang|370|

    以下均在查询分析器中运行

    一、外连接
    1.概念:包含左向外联接、右向外联接或完整外部联接

    2.左连接:left join 或 left outer join
    (1)左向外联接的结果集包含 LEFT OUTER 子句中指定的左表的全部行,而不仅仅是联接列所匹配的行。假设左表的某行在右表中沒有匹配行,则在相关联的结果集行中右表的全部选择列表列均为空值(null)。
    (2)sql语句
    select * from table1 left join table2 on table1.id=table2.id
    -------------结果-------------

    idnameidscore

    1lee190
    2zhang2100

    4wangNULLNULL

    凝视:包含table1的全部子句,依据指定条件返回table2对应的字段,不符合的以null显示

    3.右连接:right join 或 right outer join
    (1)右向外联接是左向外联接的反向联接。将返回右表的全部行。假设右表的某行在左表中沒有匹配行,则将为左表返回空值。
    (2)sql语句
    select * from table1 right join table2 on table1.id=table2.id
    -------------结果-------------

    idnameidscore

    1lee190
    2zhang2100

    NULLNULL370

    凝视:包含table2的全部子句,依据指定条件返回table1对应的字段,不符合的以null显示

    4.完整外部联接:full join 或 full outer join
    (1)完整外部联接返回左表和右表中的全部行。当某行在还有一个表中沒有匹配行时,则还有一个表的选择列表列包含空值。假设表之间有匹配行,则整个结果集行包含基表的数据值。
    (2)sql语句
    select * from table1 full join table2 on table1.id=table2.id
    -------------结果-------------

    idnameidscore

    1lee190
    2zhang2100
    4wangNULLNULL

    NULLNULL370

    凝视:返回左右连接的和(见上左、右连接)

    二、内连接
    1.概念:内联接是用比較运算符比較要联接列的值的联接

    2.内连接:join 或 inner join

    3.sql语句
    select * from table1 join table2 on table1.id=table2.id
    -------------结果-------------

    idnameidscore

    1lee190

    2zhang2100

    凝视:仅仅返回符合条件的table1和table2的列

    4.等价(与下列运行效果同样)
    A:select a.,b. from table1 a,table2 b where a.id=b.id
    B:select * from table1 cross join table2 where table1.id=table2.id (注:cross join后加条件仅仅能用where,不能用on)

    三、交叉连接(全然)

    1.概念:沒有 WHERE 子句的交叉联接将产生联接所涉及的表的笛卡尔积。第一个表的行数乘以第二个表的行数等于笛卡尔积结果集的大小。(table1和table2交叉连接产生3*3=9条记录)

    2.交叉连接:cross join (不带条件where...)

    3.sql语句
    select * from table1 cross join table2
    -------------结果-------------

    idnameidscore

    1lee190
    2zhang190
    4wang190
    1lee2100
    2zhang2100
    4wang2100
    1lee370
    2zhang370

    4wang370

    凝视:返回3*3=9条记录,即笛卡尔积

    4.等价(与下列运行效果同样)
    A:select * from table1,table2

    本文转自博客园知识天地的博客,原文链接:SQL 多个表之间联合查询,如需转载请自行联系原博主。

    展开全文
  • 一、问题的提出  在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写等体会不出SQL语句...对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见对于一个...

    一、问题的提出

        在应用系统开发初期,由于开发数据库数据比较少,对于查询SQL语句,复杂视图的编写等体会不出SQL语句各种写法的性能优劣,
    但是如果将应用系统提交实际应用后,随着数据库中数据的增加,系统的响应速度就成为目前系统需要解决的最主要的问题之一。
    系统优化中一个很重要的方面就是SQL语句的优化。对于海量数据,劣质SQL语句和优质SQL语句之间的速度差别可以达到上百倍,可见
    对于一个系统不是简单地能实现其功能就可,而是要写出高质量的 SQL 语句,提高系统的可用性。

        在多数情况下,Oracle使用索引来更快地遍历表,优化器主要根据定义的索引来提高性能。但是,如果在SQL语句的where子句中
    写的SQL代码不合理,就会造成优化器删去索引而使用全表扫描,一般就这种SQL语句就是所谓的劣质SQL语句。在编写SQL语句时我们
    应清楚优化器根据何种原则来删除索引,这有助于写出高性能的SQL语句。

    二、SQL语句编写注意问题

        下面就某些SQL语句的where子句编写中需要注意的问题作详细介绍。

        在这些where子句中,即使某些列存在索引,但是由于编写了劣质的SQL,系统在运行该SQL语句时也不能使用该索引,而同样使用
    全表扫描,这就造成了响应速度的极大降低。

        1. IS NULL 与 IS NOT NULL

        不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,
    该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。

        任何在where子句中使用is null或is not null的语句优化器是不允许使用索引的。

        2. 联接列

        对于有联接的列,即使最后的联接值为一个静态值,优化器是不会使用索引的。
        
        我们一起来看一个例子,假定有一个职工表(employee),对于一个职工的姓和名分成两列存放(FIRST_NAME和LAST_NAME),
        现在要查询一个叫比尔.克林顿(Bill Cliton)的职工。

        下面是一个采用联接查询的SQL语句,

     select * from employee
     where
     first_name||''||last_name ='Beill Cliton';

        上面这条语句完全可以查询出是否有Bill Cliton这个员工,但是这里需要注意,系统优化器对基于last_name创建的索引没有
    使用。

        当采用下面这种SQL语句的编写,Oracle系统就可以采用基于last_name创建的索引。

     Select * from employee
     where
     first_name ='Beill' and last_name ='Cliton';

        遇到下面这种情况又如何处理呢?如果一个变量(name)中存放着Bill Cliton这个员工的姓名,对于这种情况我们又如何避免
    全程遍历,使用索引呢?
        可以使用一个函数,将变量name中的姓和名分开就可以了,但是有一点需要注意,这个函数是不能作用在索引列上。
        下面是SQL查询脚本:

     select * from employee
     where
     first_name = SUBSTR('&&name',1,INSTR('&&name',' ')-1)
     and
     last_name = SUBSTR('&&name',INSTR('&&name’,' ')+1)

        3. 带通配符(%)的like语句

        同样以上面的例子来看这种情况。目前的需求是这样的,要求在职工表中查询名字中包含cliton的人。
        可以采用如下的查询SQL语句:

     select * from employee where last_name like '%cliton%';

        这里由于通配符(%)在搜寻词首出现,所以Oracle系统不使用last_name的索引。
        在很多情况下可能无法避免这种情况,但是一定要心中有底,通配符如此使用会降低查询速度。然而当通配符出现在字符串
        其他位置时,优化器就能利用索引。
        
        在下面的查询中索引得到了使用:

     select * from employee where last_name like 'c%';

        4. Order by语句

        ORDER BY语句决定了Oracle如何将返回的查询结果排序。Order by语句对要排序的列没有什么特别的限制,也可以将函数加入
    列中(象联接或者附加等)。任何在Order by语句中有非索引项或者有计算表达式都将降低查询速度。

        仔细检查order by语句以找出非索引项或者表达式,它们会降低性能。
        解决这个问题的办法就是重写order by语句以使用索引,也可以为所使用的列建立另外一个索引,同时应绝对避免在order by
    子句中使用表达式。

        5. NOT

        我们在查询时经常在where子句使用一些逻辑表达式,如大于、小于、等于以及不等于等等,也可以使用and(与)、or(或)
    以及not(非)。NOT可用来对任何逻辑运算符号取反。下面是一个NOT子句的例子:

     ... where not (status ='VALID')

        如果要使用NOT,则应在取反的短语前面加上括号,并在短语前面加上NOT运算符。NOT运算符包含在另外一个逻辑运算符中,
    这就是不等于(<>)运算符。换句话说,即使不在查询where子句中显式地加入NOT词,NOT仍在运算符中,见下例:

     ... where status <>'INVALID';

        再看下面这个例子:

     select * from employee where salary<>3000;

        对这个查询,可以改写为不使用NOT:

     select * from employee where salary<3000 or salary>3000;

        虽然这两种查询的结果一样,但是第二种查询方案会比第一种查询方案更快些。第二种查询允许Oracle对salary列使用索引,
    而第一种查询则不能使用索引。

        6. IN和EXISTS

        有时候会将一列和一系列值相比较。最简单的办法就是在where子句中使用子查询。在where子句中可以使用两种格式的子查询。

        第一种格式是使用IN操作符:

     ... where column in(select * from ... where ...);

        第二种格式是使用EXIST操作符:

     ... where exists (select 'X' from ...where ...);

        我相信绝大多数人会使用第一种格式,因为它比较容易编写,而实际上第二种格式要远比第一种格式的效率高。在Oracle中
    可以几乎将所有的IN操作符子查询改写为使用EXISTS的子查询。

        第二种格式中,子查询以‘select 'X'开始。运用EXISTS子句不管子查询从表中抽取什么数据它只查看where子句。这样优化
    器就不必遍历整个表而仅根据索引就可完成工作(这里假定在where语句中使用的列存在索引)。相对于IN子句来说,EXISTS使用
    相连子查询,构造起来要比IN子查询困难一些。

        通过使用EXIST,Oracle系统会首先检查主查询,然后运行子查询直到它找到第一个匹配项,这就节省了时间。Oracle系统在
    执行IN子查询时,首先执行子查询,并将获得的结果列表存放在一个加了索引的临时表中。在执行子查询之前,系统先将主查询
    挂起,待子查询执行完毕,存放在临时表中以后再执行主查询。这也就是使用EXISTS比使用IN通常查询速度快的原因。

        同时应尽可能使用NOT EXISTS来代替NOT IN,尽管二者都使用了NOT(不能使用索引而降低速度),NOT EXISTS要比NOT IN查
    询效率更高。

    三、索引

     1、索引分单列索引和组合索引
      单列索引:即一个索引只包含单个列,一个表可以有多个单列索引,但这不是组合索引。
      组合索引:即一个索包含多个列。

      1.普通索引。
       这是最基本的索引,它没有任何限制。它有以下几种创建方式:
       (1)创建索引:CREATE INDEX indexName ON tableName(tableColumns(length));如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是 BLOB 和 TEXT 类型,必须指定length,下同。
       (2)修改表结构:ALTER tableName ADD INDEX [indexName] ON (tableColumns(length)) 
       (3)创建表的时候直接指定:CREATE TABLE tableName ( [...], INDEX [indexName] (tableColumns(length)) ;

      2.唯一索引。
       它与前面的"普通索引"类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一。它有以下几种创建方式:
       (1)创建索引:CREATE UNIQUE INDEX indexName ON tableName(tableColumns(length))
       (2)修改表结构:ALTER tableName ADD UNIQUE [indexName] ON (tableColumns(length))
       (3)创建表的时候直接指定:CREATE TABLE tableName ( [...], UNIQUE [indexName] (tableColumns(length));

      3.主键索引
       它是一种特殊的唯一索引,不允许有空值。一般是在建表的时候同时创建主键索引:CREATE TABLE testIndex(i_testID INT NOT NULL AUTO_INCREMENT,vc_Name VARCHAR(16) NOT NULL,PRIMARY KEY(i_testID)); 当然也可以用ALTER命令。
       记住:一个表只能有一个主键。

      4.全文索引
       MySQL从3.23.23版开始支持全文索引和全文检索。这里不作讨论,呵呵~~

      删除索引的语法:DROP INDEX index_name ON tableName

     2,复合索引
      比如有一条语句是这样的:select * from users where area=’beijing’ and age=22;
      如 果我们是在area和age上分别创建单个索引的话,由于mysql查询每次只能使用一个索引,所以虽然这样已经相对不做索引时全表扫描提高了很多效率, 但是如果在area、age两列上创建复合索引的话将带来更高的效率。如果我们创建了(area, age, salary)的复合索引,那么其实相当于创建了(area,age,salary)、(area,age)、(area)三个索引,这被称为最佳左前缀 特性。因此我们在创建复合索引时应该将最常用作限制条件的列放在最左边,依次递减。

     3,索引不会包含有NULL值的列
      只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。

     4,使用短索引
      对串列进行索引,如果可能应该指定一个前缀长度。例如,如果有一个CHAR(255)的 列,如果在前10 个或20 个字符内,多数值是惟一的,那么就不要对整个列进行索引。短索引不仅可以提高查询速度而且可以节省磁盘空间和I/O操作。

     5,排序的索引问题
      mysql查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。

     6,like语句操作
      一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。

     7,不要在列上进行运算
      select * from users where YEAR(adddate)<2007;将在每个行上进行运算,这将导致索引失效而进行全表扫描,因此我们可以改成select * from users where adddate<‘2007-01-01’;

     8,不使用NOT IN和<>操作
      NOT IN和<>操作都不会使用索引将进行全表扫描。NOT IN可以NOT EXISTS代替,id<>3则可使用id>3 or id<3来代替。

    四、测试 index 用法

     1、对复合索引的测试
      
      1. 对 juren_cards 表 在 card_num 和 type_id 字段上建立 复合索引,即:create index index_c on juren_cards(card_num, type_id)
       即:将产生索引:(card_num, type_id) 和 (card_num) 两个子索引
       
       比较:没有索引时候,耗时:0.0193m

       a、单表查询:
        当 sql 是 :where card='XX' and type_id = 'XX'
        耗时:0.0006m 提高30倍

        当 sql 是 :where type_id = 'XX' and card='XX' 
        耗时:0.0006m 提高30倍,

        结论:复合索引建立成功后,查询的速度与复合索引的字段在 查询语句中where 中的先后次序 没有关系。 
       
      2. 在 1 的基础上,对 juren_card_sales 表 在 card_num 字段上 建立索引
       即:create index index_cs on juren_card_sales(card_num)

       联表查询1:
        SELECT c.*,s.* FROM `juren_cards` as c 
        left join juren_card_sales as s on s.card_num=c.card_num 
        where s.card_num='XQ1T005T202616BJ'

        比较:当 juren_card_sales 表没有建立索引 index_cs 的时候,耗时:0.0173m
        建立后:耗时 0.0010m 提高 17倍

        结论:暂时 看不出来
       
       联表查询2:
        SELECT c.*,s.* FROM `juren_cards` as c 
        left join juren_card_sales as s on s.card_num=c.card_num 
        where c.id<=1000

        比较:当 juren_card_sales 表没有建立索引 index_cs 的时候,耗时:0.4952m
        建立后:耗时 0.0020m 提高 250倍

        结论:联表的时候,对于 on 后的条件,可以对互联的表建立适当的索引,将会大大提高效率。

       联表查询3:
        SELECT c.*, s.sales_type,d.caption AS claimerDeptCaption FROM juren_cards AS c 
        LEFT JOIN juren_card_sales AS s ON c.card_num = s.card_num 
        LEFT JOIN juren_depts AS d ON d.id=c.claimer_dept_id 
        WHERE 1 = 1
        
        比较:当 juren_card_sales 表没有建立索引 index_cs 的时候,耗时:0.1645m
        建立后:耗时 0.0018m 提高近 100倍

        结论:联表的时候,对于 on 后的条件,可以对互联的表建立适当的索引,将会大大提高效率。

    展开全文
  • redis的连接池和管道

    2017-11-25 17:09:00
    NoSQL泛指非关系型的数据库 非关系型数据库和关系型数据库的差别: ...关系型数据库的优势:复杂查询可以用SQL语句方便的在一个以及表之间做非常复杂的数据查询;事务支持使得对于安全性能很高的数...
    NoSQL泛指非关系型的数据库
     
    非关系型数据库和关系型数据库的差别:
    • 性能NOSQL是基于键值对的,可以想象成表中的主键和值的对应关系,而且不需要经过SQL层的解析,所以性能非常高
    • 可扩展性同样也是因为基于键值对,数据之间没有耦合性,所以非常容易水平扩展
    • 关系型数据库的优势:复杂查询可以用SQL语句方便的在一个表以及多个表之间做非常复杂的数据查询;事务支持使得对于安全性能很高的数据访问要求得以实现
    • 对于这两类数据库,对方的优势就是自己的弱势,所以如何利用好这两种数据库的强项,使其相互补充,是一个很重要的需要好好设计的问题

     

    redis简介

    redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)
    这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序
    与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了主从同步
     
    redis官网:https://redis.io/
    redis中文网:http://www.redis.net.cn/
     
     
     
    redis服务端安装
    [root@web ~]# cd /usr/local/src/
    [root@web src]# wget http://download.redis.io/releases/redis-3.2.5.tar.gz
    [root@web src]# tar -zxf redis-3.2.5.tar.gz
    [root@web src]# cd redis-3.2.5
    [root@web redis-3.2.5]# make
    
    [root@web redis-3.2.5]# vim /usr/local/src/redis-3.2.5/redis.conf     //默认配置文件,把daemonize no  改为daemonize yes,允许后台启动
    
    [root@web redis-3.2.5]# cd src
    [root@web src]# pwd
    /usr/local/src/redis-3.2.5/src
    [root@web src]# ls
    -rwxr-xr-x 1 root root 5580311 11月 25 11:18 redis-benchmark          //基准测试      
    -rwxr-xr-x 1 root root   22185 11月 25 11:18 redis-check-aof          //aof持久化
    -rwxr-xr-x 1 root root 7826902 11月 25 11:18 redis-check-rdb          //rdb持久化
    -rwxr-xr-x 1 root root 5709036 11月 25 11:18 redis-cli                //linux上的redis客户端
    -rwxr-xr-x 1 root root 7826902 11月 25 11:18 redis-sentinel           //哨兵,用于redis集群选举
    -rwxr-xr-x 1 root root 7826902 11月 25 11:18 redis-server             //redis服务端程序
    
    [root@web src]# ./redis-server /usr/local/src/redis-3.2.5/redis.conf         //启动redis
    
    [root@web src]# netstat -lnp                                                 //监听127.0.0.1:6379
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name   
    tcp        0      0 127.0.0.1:6379              0.0.0.0:*                   LISTEN      4443/./redis-server

     

    redis客户端安装

    [root@web ~]# pip install redis
    
    [root@web ~]# ipython
    In [1]: import redis
    注意:默认配置文件定义监听localhost
             如果客户端和服务端不在同一台服务器上,服务端的配置文件监听地址需要改为bind 0.0.0.0
     
     
    redis客户端的使用
    [root@web redis_py]# cat demon1.py
    #!/usr/bin/env python
    
    import redis
    
    r = redis.Redis(host='localhost', port=6379, db=0, password=None)       //实例化Redis这个类获得一个对象r,对象的方法就是redis的所有命令
    r.set('name', 'aaa')                                                    //set()方法往服务端存入两个键值对
    r.set('age', 30)
    print r.get('name')                                                     //get(key)方法获取key对应的value
    print r.keys()                                                          //keys()方法打印所有的key
    
    [root@web redis_py]# python demon1.py
    aaa
    ['age', 'name']

     

     

    redis连接池

    redis客户端使用连接池管理所有请求服务端的连接,避免每次建立、释放连接造成多余的开销
    默认情况下,每个redis实例都会维护自己的连接池
    可以直接建立一个连接池,实例化对象的时候使用连接池作为参数,这样可以实现多个redis实例共享连接池
    [root@web redis_py]# cat demon2.py   
    #!/usr/bin/env python
    
    import redis
    
    def getConnection():
        config = {
            'host': 'localhost',
            'port': 6379,
            'db': 0,
            'password': None
        }
        pool = redis.ConnectionPool(**config)
        r = redis.Redis(connection_pool=pool)
        return r
    
    
    if __name__ == '__main__':
        r = getConnection()
        r.set('gender', 'M')
        print r.get('gender')
    
    
    [root@web redis_py]# python demon2.py
    M

     

     

    管道:

    redis客户端执行每次请求都会向连接池申请创建连接,请求完毕断开连接
    redis是c/s模式的tcp server,使用和http类型的请求响应协议。一个client可以通过socket连接向服务端发起多个请求,每发送一个请求后,client会阻塞并等待redis服务端响应,服务端处理完请求后悔将结果通过响应报文返回给client,也就是说client一次只能发送一个请求
     
    client: INCR X
    server: 1
    client: INCR X
    server: 2
    client: INCR X
    server: 3
    client: INCR X
    server: 4
     
    基本上四个命令需要8个tcp报文才能完成,由于通信会有网络延迟,假如从client和server之间的包传输时间需要0.125秒,那么上面的四个命令8个报文至少会需要1秒才能完成,这样即使redis每秒能处理100个命令,而我们的client也只能一秒钟发出四个命令,没有充分利用 redis的处理能力
     
    客户端要想一次发送多个请求,需要使用mset、mget等命令,或者使用管道
    client可以将四个命令放到一个tcp报文一起发送,server则可以将四条命令的处理结果放到一个tcp报文返回
    需要注意的是,用pipeline方式打包命令发送,redis在处理完所有请求后会缓存请求结果到内存中。打包的命令越多,缓存消耗内存也越多。所以并是不是打包的命令越多越好。具体多少合适需要根据具体情况测试
     
    client: INCR X
    client: INCR X
    client: INCR X
    client: INCR X
    server: 1
    server: 2
    server: 3
    server: 4
     
     
    管道的用法:
    In [6]: help(r.pipeline)
    Help on method pipeline in module redis.client:
    
    pipeline(self, transaction=True, shard_hint=None) method of redis.client.Redis instance           //获取一个连接对象,通过连接对象创建一个管道
        Return a new pipeline object that can queue multiple commands for                             //返回一个管道对象
        later execution. ``transaction`` indicates whether all commands                               //自动执行多条命令(把多个请求发送到服务端)
        should be executed atomically. Apart from making a group of operations
        atomic, pipelines are useful for reducing the back-and-forth overhead                         //提高处理能力
        between the client and server

     

    使用管道和不使用管道的效率对比:

    [root@web redis_py]# cat demon3.py
    #!/usr/bin/env python
    
    import redis
    import datetime
    from demon2 import getConnection
    
    def withpipeline(r):
        p = r.pipeline(transaction=True)
        for i in xrange(1000):
            key = 'test1' + str(i)
            value = i+1
            p.set(key, value)
        p.execute()
    
    def withoutpipeline(r):
        for i in xrange(1000):
            key = 'test2' + str(i)
            value = i+1
            r.set(key, value)
    
    if __name__ == '__main__':
        r = getConnection()
        start = datetime.datetime.now()
        withpipeline(r)
        end = datetime.datetime.now()
        offset = (end-start).microseconds
        print 'With pipeline time: {0}'.format(offset)
        start = datetime.datetime.now()
        withoutpipeline(r)
        end = datetime.datetime.now()
        offset = (end-start).microseconds
        print 'Without pipeline time: {0}'.format(offset)
    
    
    [root@web redis_py]# python demon3.py
    With pipeline time: 16403
    Without pipeline time: 43398

     

     

    转载于:https://www.cnblogs.com/tobeone/p/7895802.html

    展开全文
  • 所以select具有O(n)差别轮询复杂度,同时处理流越,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入数组拷贝到内核空间,然后查询每个fd对应设备状态...
  • 所以select具有O(n)差别轮询复杂度,同时处理流越,无差别轮询时间就越长。 poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入数组拷贝到内核空间,然后查询每个fd对应设备状态, ...
  • 数据结构之链表

    2021-05-20 10:41:03
    文章目录数据结构之链表顺序和线性表区别单向线性表头文件源文件双向线性表头文件源文件 数据结构之链表 ...每个结点之间通过指针域进行连接。 顺序和线性表区别 什么是顺序,和线性表差别在哪里? 简
  • 所以select具有O(n)差别轮询复杂度,同时处理流越,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入数组拷贝到内核空间,然后查询每个fd对应设备状态...
  • 所以select具有O(n)差别轮询复杂度,同时处理流越,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入数组拷贝到内核空间,然后查询每个fd对应设备状态, ...
  • 所以select具有O(n)差别轮询复杂度,同时处理流越,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入数组拷贝到内核空间,然后查询每个fd对应设备状态...
  • 所以select具有O(n)差别轮询复杂度,同时处理流越,无差别轮询时间就越长。 (2)poll==>时间复杂度O(n) poll本质上和select没有区别,它将用户传入数组拷贝到内核空间,然后查询每个fd对应设备状态...
  • 非关系型数据库和关系型数据库的差别: 非关系型数据库的优势: ...复杂查询可以用SQL语句方便的在一个以及表之间做非常复杂的数据查询。 事务支持使得对于安全性能很高的数据访问要求得...
  • 多表连接join子句有三种分类, inner join(默认,查询满足条件选中列), left join(查询满足条件左表列和选中列), right join(查询满足条件右表列和选中列), full outer join(查询全部) ...
  • sql性能优化

    2019-01-17 10:29:42
    在使用连接查询时候最好以数据量小表... 当表数据量很大并且要多表查询话,如果有条件筛选,最好先在每个表中先使用条件筛选之后再进行连接,以前亲测,本地三张表一张 2.5万,一张78万,一张1700,三张表一...
  • sql优化

    2019-06-05 14:08:52
    数据库采用自右而左的顺序解析WHERE子句,根据这个原理,表之间的连接必须写在其他WHERE条件之左,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的之右。 emp.sal可以过滤条记录,写在WHERE字句的最右边 sel...
  • 重写Overriding是父类与子类之间多态性一种表现,重载Overloading是一个类中态性一种表现。如果在子类中定义某方法与其父类有相同名称和参数,我们说该方法被重写 (Overriding)。子类对象使用这个方法时,...
  • SQL集合与链接草稿

    2020-12-22 23:35:47
    2、通过上述 bag 与 set 定义之间的差别我们就发现, 使用 bag 模型来描述数据库中的在很时候更加合适:用UNION 实现并、用 IN 实现交、用NOT IN实现差(补集); 3、用视图实现: 二、连接 1、 4.2.1.3...
  • 人类与简单生物巨大差别,来自蛋白质之间相互作用数量 蛋白质定义:一类重要生物高分子,参与了生物体内几乎所有生理功能和代谢过程。由20种氨基酸通过肽键(酰胺键)连接形成长链分子(肽链),在...
  • MySQL命令大全

    2018-01-15 11:19:17
    例如,往 MyClass中插入二条记录, 这二条记录表示:编号为名为Tom成绩为.45, 编号为 名为Joan 成绩为.99,编号为 名为Wang 成绩为.5. mysql>insert into MyClass values(1,’Tom’,96.45),(2,’Joan...

空空如也

空空如也

1 2 3 4 5 ... 7
收藏数 121
精华内容 48
关键字:

多表连接之间的差别