最近一段时间,翻阅了《SQL学习指南》这本书,发现了一些值得记下的使用技巧和容易忽视的知识点
一·关于查询:
1.1·可以通过在SELECT后面加上DISTINCT来去除结果集中重复的行。默认的SELECT后面适用的是ALL关键字。
1.2·对于DISTINCT的使用,执行时会先对结果集进行排序,比较耗时。所以不必要的时候应该减少使用。
1.3·表分为三类:永久表、临时表、虚拟表(视图)。可以通过CREATE VIEW EMP_VW AS SELECT * FROM EMPLOYEE_来创建名为EMP_VW 的视图。
1.4·使用虚拟表:SELECT * FROM EMP_VW 。
1.5·ORDER BY 1 表明使用返回结果的第一列进行排序。
二·关于过滤:
2.1·所有的SQL,除了INSERT外,都可以使用WHERE进行数据过滤。
2.2·BETWEEN......AND...... 对字符串进行排序,实际是按照字符串在所使用字符集内顺序进行排序的。
2.3·REGEXP 在MYSQL中,可以使用该关键字来通过正则表达式对数据进行验证。Oracle中格式为REGEXP_LIKE 。SQL Server中,可以直接写在LIKE关键字后面。
2.4·两个NULL,不能进行相等的判断。如果数据中存在NULL是,通过 列名 != 值 的形式,不能取到值为NULL的数据。
三·多表查询:
3.1·交叉查询 CROSS JOIN (取得笛卡尔积)。
3.2·内连接 INNER JOIN ,对于内连接连接的两个表,只有两张表中通过连接条件的数据行,才能够查询出来。
3.3·关于SQL的连接顺序:SQL是一种非过程化语言,对于FROM自己中级联的各个表,SQL会根据表内数据行的数量自动进行重新排序,可以通过关键字指定级联的先后顺序。
3.4·自连接 对于表自身进行连接。例如 地区级联,通过地区的PARENT_ID_,级联他自身的主键ID_ 。
四·使用集合:
4.1·UNION和UNION ALL操作。UNION操作会去除重复的行,而UNION ALL则不会去除重复的行。
4.2·INTERECT和INTERECT ALL操作。取交集(去重,不去重)。
4.3·EXCEPT 和 EXCEPT ALL 操作。集合差(去重,不去重)。
4.4·使用UNION时,如果需要排序,只能对UNION中第一个表中字段名进行排序。所以,不要将两张表的列名写成一样的。
4.5·复合查询的顺序是自顶向下进行的,其中INTERECT的优先级最高。
五·数据转换以及生成:
5.1·当存入数据库中的字符串超过我们设定的长度时,数据库会有以下两种处理方式:
一、添加到数据库,对字符串进行截串操作,并提示警告信息。(ANSI)
二、抛异常。(STRICT)
对于处理的模式,我们可以通过 SELECT @@session.sql_mode;来进行查询。我们还可以通过 SET SQL_MODE = 'ANSI'; 来设定SQL模式。
5.2·在查询语句中使用char()函数可以取得字符对应的ASCII码,通过ASCII()函数可以通过ASCII码取得对应字符。
5.3·Mysql中使用CONCAT('exp1','exp2','exp3'....)来进行字符串的连接。
5.4·length(colunmName) 。 在length(col)函数中放入列的字段名,可以返回该列的字符串长度。对于MySQL,Oracle中,char类型的列中存放的字符串,只用空格填充向右补齐,但在获取数据的时候,会自动删除掉尾端的空格。
5.5·position('character' IN vchar_fld).找出字符串character在vchar_fld中的位置,若找不到,则返回0 。
ADO.net提供了一个断开的体系结构,也就是说,应用程序与数据库连接后,将检索到的数据保存到内存中,然后断开数据库;
当处理数据时,只需处理内存中的数据即可,处理完后,打开数据库连接,再更新到数据库
用于在内存中保存数据的主要是DataSet,它包含了其他存储在内存中的数据,例如:DataTable对象。
使用断开的体系结构的好处:1,允许应用程序按比例增长;即:无论1000个用户还是10用户访问数据库,数据库表现的都一样好.
因为:2,这些应用程序连接数据库的时间仅仅是检索或更新数据时需要的时间,之后就断开连接;
因此释放了可用的数据库连接,以实现与应用程序其他实例的连接,或与使用同一数据库的其他应用程序的连接.
而不是所有应用程序都在数据库中直接处理数据.
即:下图
总结:建立连接—检索到的数据保存在数据集—关闭连接—数据集中处理数据—打开连接—处理的数据更新到数据库—关闭连接
也就是说,每个应用程序只在检索和更新数据时和数据库建立连接;
读操作
在数据库的四种基础操作中,读操作是指那些从MongoDB聚集中检索记录或文档的操作。
你可以通过以下任意一种方法从MongoDB中检索文档:
1.find
2.findOne
Find
find方法是从聚集中检索众多文档的基础方法,find()方法返回包含若干文档的cursor。大多数的
驱动程序都向应用程序开发者提供了一种本地的可遍历借口来处理cursor和遍历文档。find()方法
包含如下句法:
db.collection.find( <query>, <projection> )
SQL中类似的操作:find()方法类似于SQL中的SELECT语句。
1.<query>参数类似于WHERE字句,而且
2.<projection>参数类似于将要从结果集合中检索的目标字段。
通过下面的示例来阐述find()方法的使用:
这个示例相关于一个bios的聚集,该聚集中有如下文档原型:
{
"_id" : 1,
"name" : {
"first" : "John",
"last" :"Backus"
},
"birth" : ISODate("1924-12-03T05:00:00Z"),
"death" : ISODate("2007-03-17T04:00:00Z"),
"contribs" : [ "Fortran", "ALGOL", "Backus-Naur Form", "FP" ],
"awards" : [
{
"award" : "W.W. McDowellAward",
"year" : 1967,
"by" : "IEEE Computer Society"
},
{
"award" : "National Medal of Science",
"year" : 1975,
"by" : "National Science Foundation"
},
{
"award" : "Turing Award",
"year" : 1977,
"by" : "ACM"
},
{
"award" : "Draper Prize",
"year" : 1993,
"by" : "National Academy of Engineering"
}
]
}
注意:在mongo shell中,你可以通过在find()后面添加.pertty()来格式化输出。
1.如果没有<query>参数,find()方法会返回聚集中的所有文档,
下面的操作返回bios聚集中的所有文档,(更精确的说法,返回一个cursor)
db.bios.find()
2.如果有<query>参数,find()方法会从聚集的所有文档中选择满足query标准的。
下面的扫做返回bios聚集中所有_id字段为5或者ObjectId("507c35dd8fada716c89d0013")
db.bios.find(
{
_id: { $in: [ 5, ObjectId("507c35dd8fada716c89d0013") ] }
}
)
下面的操作返回bios聚集中array字段contribs中包含unix的文档:
db.bios.find(
{
contribs: 'UNIX'
}
)
下面操作返回bios聚集中array字段awards包含一个子文档,该子文档包含award字段里有T如ing Arard
而且year字段大于1980:
db.bios.find(
{
awards: {
$elemMatch: {
award: 'Turing Award',
year: { $gt: 1980 }
}
}
}
)
下面的操作返回bios聚集中一个子文档“name"中包含字段first值为”Yukihiro“而且
last字段值为”Matsumoto“,quer通过.操作符来访问子文档的字段:
db.bios.find(
{
'name.first': 'Yukihiro',
'name.last': 'Matsumoto'
}
)
实际上,上面的操作对于下面连各种情况都会匹配:
{
first: 'Yukihiro',
aka: 'Matz',
last: 'Matsumoto'
}
{
last: 'Matsumoto',
first: 'Yukihiro'
}
下面的操作会返回bios聚集中子文档name字段确切的{ first: 'Yukihiro', last: 'Matsumoto' },并且顺序
也一致: