游标

游标 游标 (cursor) 是系统为用户开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字。用户可以用SQL语句逐一从游标中获取记录,并赋给主变量,交由主语言进一步处理。 主语言是面向记录的,一组主变量一次只能存放一条记录。仅使用主变量并不能完全满足SQL语句向应用程序输出数据的要求。嵌入式SQL引入了游标的概念,用来协调这两种不同的处理方式。在数据库开发过程中,当你检索的数据只是一条记录时,你所编写的事务语句代码往往使用SELECT INSERT 语句。但是我们常常会遇到这样情况,即从某一结果集中逐一地读取一条记录。那么如何解决这种问题呢?游标为我们提供了一种极为优秀的解决方案。 1.游标和游标的优点 在数据库中,游标是一个十分重要的概念。游标提供了一种对从表中检索出的数据进行操作的灵活手段,就本质而言,游标实际上是一种能从包括多条数据记录的结果集中每次提取一条记录的机制。游标总是与一条SQL 选择语句相关联因为游标由结果集 (可以是零条、一条或由相关的选择语句检索出的多条记录) 和结果集中指向特定记录的游标位置组成。当决定对结果集进行处理时,必须声明一个指向该结果集的游标。如果曾经用 C 语言写过对文件进行处理的程序,那么游标就像您打开文件所得到的文件句柄一样,只要文件打开成功,该文件句柄就可代表该文件。对于游标而言,其道理是相同的。可见游标能够实现按与传统程序读取平面文件类似的方式处理来自基础表的结果集,从而把表中数据以平面文件的形式呈现给程序。 我们知道关系数据库管理系统实质是面向集合的,在MS SQL SERVER 中并没有一种描述表中单一记录的表达形式,除非使用where 子句来限制只有一条记录被选中。因此我们必须借助于游标来进行面向单条记录的数据处理。由此可见,游标允许应用程序对查询语句select 返回的行结果集中每一行进行相同或不同的操作,而不是一次对整个结果集进行同一种操作;它还提供对基于游标位置而对表中数据进行删除或更新的能力;而且,正是游标把作为面向集合的数据库管理系统和面向行的程序设计两者联系起来,使两个数据处理方式能够进行沟通。

Created 16166-04-16 · Updated 16166-04-16 · 1 min · 20 words · -

左外连接,右外连接,全连接,内连接

左外连接,右外连接,全连接,内连接, left join, right join 外联接: 外联接可以是左向外联接、右向外联接或完整外部联接。 在 FROM 子句中指定外联接时,可以由下列几组关键字中的一组指定: LEFT JOIN 或 LEFT OUTER JOIN, SQL 标准允许省略 OUTER 关键字,因此 LEFT JOIN 已经足够明确。 左向外联接的结果集包括 LEFT OUTER 子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。 如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。 RIGHT JOIN 或 RIGHT OUTER JOIN。 右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。 FULL JOIN 或 FULL OUTER JOIN。 完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。 仅当至少有一个同属于两表的行符合联接条件时,内联接才返回行。内联接消除与另一个表中的任何行不匹配的行。而外联接会返回 FROM 子句中提到的至少一个表或视图的所有行,只要这些行符合任何 WHERE 或 HAVING 搜索条件。将检索通过左向外联接引用的左表的所有行,以及通过右向外联接引用的右表的所有行。完整外部联接中两个表的所有行都将返回。 Microsoft® SQL Server 2000 对在 FROM 子句中指定的外联接使用以下 SQL-92 关键字: LEFT OUTER JOIN 或 LEFT JOIN RIGHT OUTER JOIN 或 RIGHT JOIN ...

Created 20206-03-20 · Updated 20206-03-20 · 4 min · 657 words · -

Hsqldb

Hsqldb Hsqldb是一个开放源代码的JAVA数据库,其具有标准的SQL语法和JAVA接口, 在HSQLDB中,有三种比较常用模式: 服务器模式 Server模式提供了最大的可访问性。应用程序 (客户端) 通过Hsqldb的JDBC驱动连接服务器。在服务器模式中,服务器在运行的时候可以被指定为最多10个数据库。根据客户端和服务器之间通信协议的不同,Server模式可以分为以下三种: 1、 Hsqldb Serve 这种模式是首选的也是最快的。它采用HSQLDB专有的通信协议。启动服务器需要编写批处理命令。Hsqldb提供的所有工具都能以java class归档文件(也就是jar)的标准方式运行。假如hsqldb.jar位于相对于当前路径的../lib下面。我们的命令将这样写: java -cp ../lib/hsqldb.jar org.hsqldb.Server -database.0 mydb -dbname.0 demoDB 现在你可能会疑惑,[-database.0 ]、 [dbname.0]为什么在后面加[0]。_… …我们不是在前面说服务模式运行的时候可以指定10个数据库吗,如有多个数据库,则继续写命令行参数-database.1 aa -dbname.1 aa -database.2 bb-dbname.2 bb … … 新建文本文件保存上面命令,文件名可以随意,将后缀名改成bat,然后直接执行批处理文件即可。在以后介绍的执行启动工具的命令采用同样方法。 上面启动服务器的命令启动了带有一个 (默认为一个数据库) 数据库的服务器,这个数据库是一个名为"mydb.*“文件,这些文件就是mydb.Properties、mydb.script、mydb.log等文件。其中demoDB是mydb的别名,可在连接数据库时使用。 2、 Hsqldb Web Server 这种模式只能用在通过HTTP协议访问数据库服务器主机,采用这种模式唯一的原因是客户端或服务器端的防火墙对数据库对网络连接强加了限制。其他情况下,这种模式不推荐被使用。 运行web服务器的时候,只要将刚才命令行中的主类 (main class) 替换成: org.hsqldb.WebServer 3、 Hsqldb Servlet 这种模式和Web Server一样都采用HTTP协议,当如Tomcat或Resin等servlet引擎 (或应用服务器) 提供数据库的访问时,可以使用这种模式。但是Servlet模式不能脱离servlet引擎独立启动。为了提供数据库的连接,必须将HSQLDB.jar中的hsqlServlet类放置在应用服务器的相应位置。 Web Server和Servlet模式都只能在客户端通过JDBC驱动来访问。Servlet模式只能启动一个单独的数据库。请注意做为应用程序服务器的数据库引擎通常不使用这种模式。 连接到以Server模式运行的数据库 当HSQLDB服务器运行时,客户端程序就可以通过hsqldb.jar中带有的HSQLDB JDBC Driver连接数据库。 java 代码 try{ Class.forName(“org.hsqldb.jdbcDriver”) ; }catch(ClassNotFoundException e){ e.printStackTrace(); } Connection c = DriverManager.getConnection(“jdbc:hsqldb:hsql://localhost/xdb”, “sa”, “”); ...

Created 23236-02-23 · Updated 23236-02-23 · 1 min · 173 words · -

MySQL limit

MySQL limit SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset SELECT 语句返回指定的记录数 LIMIT 接受一个或两个数字参数。参数必须是整数常量。如果输入两个参数,第一个参数指定返回记录的偏移量,第二个参数指定返回记录行的最大数目。第一条记录行的偏移量是 0(不是 1): 为了与 PostgreSQL 兼容,MySQL 也支持语法: LIMIT # OFFSET #。 SELECT * FROM table LIMIT 2,1; //从第2条开始读,读取1条信息。 MySQL> SELECT * FROM table LIMIT 5,10; // 检索 6-15 行 //为了检索从某一个偏移量到记录集的结束所有的记录行,可以指定第二个参数为 -1: SELECT FROM table LIMIT 95,-1; // 检索记录行 96-last. //如果只给定一个参数,它表示返回最大的记录行数目: SELECT FROM table LIMIT 5; //检索前 5 个记录行 //换句话说,LIMIT n 等价于 LIMIT 0,n。 如果是oracle 可以用rownum实现相同的功能。 ...

Created 3036-02-03 · Updated 3036-02-03 · 1 min · 72 words · -

MyBatis动态传入表名,字段名的解决办法

MyBatis动态传入表名,字段名的解决办法 http://springsfeng.iteye.com/blog/1634234 参考: http://luoyu-ds.iteye.com/blog/1517607 如果要动态传入表名,字段名之类的参数替换SQL语句中的占位副,需要将SQL语句执行改成非预编译的,即: Xml代码 <img alt="收藏代码" src="http://springsfeng.iteye.com/images/icon_star.png" /> statementType="STATEMENT" > <![DATA[ updata user_info_t set ${field} = ${value} where id= ${id} ]]> </update> 同时参数Map中需做下面处理: Java代码 <img alt="收藏代码" src="http://springsfeng.iteye.com/images/icon_star.png" /> Map<String, Object> map = new HashMap<String, Object>(); map.put("field", Constant.ISSUED_PLAN_COLUMN_NAME.get(field)); map.put("value", "'"+value+"'"); map.put("id", id);

Created 24246-01-24 · Updated 24246-01-24 · 1 min · 43 words · -

PreparedStatement

PreparedStatement jdbc(java database connectivity,java数据库连接)的api中的主要的四个类之一的java.sql.statement要求开发者付出大量的时间和精力。在使用statement获取jdbc访问时所具有的一个共通的问题是输入适当格式的日期和时间戳: 2002-02-05 20:56 或者 02/05/02 8:56 pm。 通过使用java.sql.preparedstatement,这个问题可以自动解决。一个preparedstatement是从java.sql.connection对象和所提供的sql字符串得到的,sql字符串中包含问号 (?) ,这些问号标明变量的位置,然后提供变量的值,最后执行语句,例如: stringsql = “select * from people p where p.id = ? and p.name = ?”; preparedstatement ps = connection.preparestatement(sql); ps.setint(1,id); ps.setstring(2,name); resultset rs = ps.executequery(); 使用preparedstatement的另一个优点是字符串不是动态创建的。下面是一个动态创建字符串的例子: stringsql = “select * from people p where p.i = “+id; 这允许jvm (javavirtual machine,java虚拟机) 和驱动/数据库缓存语句和字符串并提高性能。 preparedstatement也提供数据库无关性。当显示声明的sql越少,那么潜在的sql语句的数据库依赖性就越小。 由于preparedstatement具备很多优点,开发者可能通常都使用它,只有在完全是因为性能原因或者是在一行sql语句中没有变量的时候才使用通常的statement。

Created 16166-01-16 · Updated 16166-01-16 · 1 min · 56 words · -

BLOB

BLOB BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。 在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。 BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理 (例如: 上传、下载或者存放到一个数据库) 。 根据Eric Raymond的说法,处理BLOB的主要思想就是让文件处理器 (如数据库管理器) 不去理会文件是什么,而是关心如何去处理它。 但也有专家强调,这种处理大数据对象的方法是把双刃剑,它有可能引发一些问题,如存储的二进制文件过大,会使数据库的性能下降。在数据库中存放体积较大的多媒体对象就是应用程序处理BLOB的典型例子。 大型对象 BLOB就是使用二进制保存数据。 如: 保存位图。 CLOB使用CHAR来保存数据。 如: 保存XML文档。 Oracle中的BLOB和CLOB LONG: 可变长的字符串数据,最长2G,LONG具有VARCHAR2列的特性,可以存储长文本一个表中最多一个LONG列 LONG RAW: 可变长二进制数据,最长2G CLOB: 字符大对象Clob 用来存储单字节的字符数据 NCLOB: 用来存储多字节的字符数据 BLOB: 用于存储二进制数据 BFILE: 存储在文件中的二进制数据,这个文件中的数据只能被只读访。但该文件不包含在数据库内。 bfile字段实际的文件存储在文件系统中,字段中存储的是文件定位指针.bfile对oracle来说是只读的,也不参与事务性控制和数据恢复. CLOB,NCLOB,BLOB都是内部的LOB(Large Object)类型,最长4G,没有LONG只能有一列的限制 要保存图片、文本文件、Word文件各自最好用哪种数据类型? -BLOB最好,LONGRAW也不错,但Long是oracle将要废弃的类型,因此建议用BLOB。 Blob是指二进制大对象也就是英文Binary Large Object的所写,而Clob是指大字符对象也就是英文Character Large Object的所写。由此可见这辆个类型都是用来存储大量数据而设计的,其中BLOB是用来存储大量二进制数据的;CLOB用来存储大量文本数据。 那么有人肯定要问既然已经有VARCHAR和VARBINARY两中类型,为什么还要再使用另外的两种类型呢?其实问题很简单,VARCHAR和VARBINARY两种类型是有自己的局限性的。首先说这两种类型的长度还是有限的不可以超过一定的限额,以VARCHAR再ORA中为例长度不可以超过4000;那么有人又要问了,LONGVARCHAR类型作为数据库中的一种存储字符的类型可以满足要求,存储很长的字符,那为什么非要出现CLOB类型呢?其实如果你用过LONGVARCHAR类型就不难发现,该类型的一个重要缺陷就是不可以使用LIKE这样的条件检索。 (稍候将介绍在CLOB中如何实现类似LIKE的模糊查找) 另外除了上述的问题外,还又一个问题,就是在数据库中VARCHAR和VARBINARY的存取是将全部内容从全部读取或写入,对于100K或者说更大数据来说这样的读写方式,远不如用流进行读写来得更现实一些。 在JDBC中有两个接口对应数据库中的BLOB和CLOB类型,java.sql.Blob和java.sql.Clob。和你平常使用数据库一样你可以直接通过ResultSet.getBlob()方法来获取该接口的对象。与平时的查找唯一不同的是得到Blob或Clob的对象后,我们并没有得到任何数据,但是我们可以这两个接口中的方法得到数据 例如: Blob b=resultSet.getBlob(1); InputStream bin=b.getBinaryStryeam(); Clob c=resultSet.getClob(2); Reader cReader=c.getCharacterStream(): 关于Clob类型的读取可以使用更直接的方法,就是直接通过ResultSet.getCharacterStream();方法获得字符流,但该方法并不安全,所以建议还是使用上面例子的方法获取Reader。 另外还有一种获取方法,不使用数据流,而是使用数据块。 例如 Blob b=resultSet.getBlob(1); byte data=b.getByte(0,b.length()); Clob c=resultSet.getClob(2); String str=c.getSubString(0,c.length()): 在这里我要说明一下,这个方法其实并不安全,如果你很细心的话,那很容易就能发现getByte()和getSubString()两个方法中的第二个参数都是int类型的,而BLOB和CLOB是用来存储大量数据的。而且Bolb.length()和Clob.length()的返回值都是long类型的,所以很不安全。这里不建议使用。但为什么要在这里提到这个方法呢?稍候告诉你答案,这里你需要记住使用数据块是一种方法。 ...

Created 15156-01-15 · Updated 15156-01-15 · 1 min · 202 words · -

jdbc driver

jdbc driver jdbc driver: com.MySQL.jdbc.Driver oracle.jdbc.driver.OracleDriver jdbc url: jdbc:MySQL://localhost:3306/xxxxxx jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:xxxxxx

Created 8086-12-08 · Updated 8086-12-08 · 1 min · 10 words · -

Database

Database SQL tuning 类 列举几种表连接方式 等连接 (内连接) 、非等连接、自连接、外连接 (左、右、全) Or hash join/merge join/nest loop(cluster join)/index join ?? ORACLE 8i,9i 表连接方法。 一般的相等连接: select * from a, b where a.id = b.id; 这个就属于内连接。 对于外连接: Oracle中可以使用"(+) “来表示,9i可以使用LEFT/RIGHT/FULL OUTER JOIN LEFT OUTER JOIN: 左外关联 SELECT e.last_name, e.department_id, d.department_name FROM employees e LEFT OUTER JOIN departments d ON (e.department_id = d.department_id); 等价于 SELECT e.last_name, e.department_id, d.department_name FROM employees e, departments d WHERE e.department_id=d.department_id(+) 结果为: 所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。 RIGHT OUTER JOIN: 右外关联 SELECT e.last_name, e.department_id, d.department_name FROM employees e RIGHT OUTER JOIN departments d ON (e.department_id = d.department_id); 等价于 SELECT e.last_name, e.department_id, d.department_name FROM employees e, departments d WHERE e.department_id(+)=d.department_id 结果为: 所有员工及对应部门的记录,包括没有任何员工的部门记录。 FULL OUTER JOIN: 全外关联 SELECT e.last_name, e.department_id, d.department_name FROM employees e FULL OUTER JOIN departments d ON (e.department_id = d.department_id); 结果为: 所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录和没有任何员工的部门记录。 ORACLE8i是不直接支持完全外连接的语法,也就是说不能在左右两个表上同时加上(+),下面是在ORACLE8i可以参考的完全外连接语法 select t1.id,t2.id from table1 t1,table t2 where t1.id=t2.id(+) union select t1.id,t2.id from table1 t1,table t2 where t1.id(+)=t2.id ...

Created 27276-11-27 · Updated 27276-11-27 · 15 min · 3180 words · lcf

数据库索引

数据库索引 数据库索引好比是一本书前面的目录,能加快数据库的查询速度。 例如这样一个查询: select * from table1 where id=44。如果没有索引,必须遍历整个表,直到ID等于44的这一行被找到为止;有了索引之后(必须是在ID这一列上建立的索引),直接在索引里面找44 (也就是在ID这一列找) ,就可以得知这一行的位置,也就是找到了这一行。可见,索引是用来定位的。 索引分为聚簇索引和非聚簇索引两种,聚簇索引 是按照数据存放的物理位置为顺序的,而非聚簇索引就不一样了;聚簇索引能提高多行检索的速度,而非聚簇索引对于单行的检索很快。为表设置索引要付出代价的: 一是增加了数据库的存储空间,二是在插入和修改数据时要花费较多的时间(因为索引也要随之变动)。 详述 创建索引可以大大提高系统的性能。第一,通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。第二,可以大大加快数据的检索速度,这也是创建索引的最主要的原因。第三,可以加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。第四,在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。第五,通过使用索引,可以在查询的过程中,使用优化隐藏器,提高系统的性能。 也许会有人要问: 增加索引有如此多的优点,为什么不对表中的每一个列创建一个索引呢?因为,增加索引也有许多不利的方面。第一,创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加。第二,索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大。第三,当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度。 索引是建立在数据库表中的某些列的上面。在创建索引的时候,应该考虑在哪些列上可以创建索引,在哪些列上不能创建索引。一般来说,应该在这些列上创建索引: 在经常需要搜索的列上,可以加快搜索的速度; 在作为主键的列上,强制该列的唯一性和组织表中数据的排列结构; 在经常用在连接的列上,这些列主要是一些外键,可以加快连接的速度;在经常需要根据范围进行搜索的列上创建索引,因为索引已经排序,其指定的范围是连续的; 在经常需要排序的列上创建索引,因为索引已经排序,这样查询可以利用索引的排序,加快排序查询时间; 在经常使用在WHERE子句中的列上面创建索引,加快条件的判断速度。 同样,对于有些列不应该创建索引。一般来说,不应该创建索引的的这些列具有下列特点: 第一,对于那些在查询中很少使用或者参考的列不应该创建索引。这是因为,既然这些列很少使用到,因此有索引或者无索引,并不能提高查询速度。相反,由于增加了索引,反而降低了系统的维护速度和增大了空间需求。 第二,对于那些只有很少数据值的列也不应该增加索引。这是因为,由于这些列的取值很少,例如人事表的性别列,在查询的结果中,结果集的数据行占了表中数据行的很大比例,即需要在表中搜索的数据行的比例很大。增加索引,并不能明显加快检索速度。 第三,对于那些定义为text, image和bit数据类型的列不应该增加索引。这是因为,这些列的数据量要么相当大,要么取值很少,不利于使用索引。 第四,当修改性能远远大于检索性能时,不应该创建索引。这是因为,修改性能和检索性能是互相矛盾的。当增加索引时,会提高检索性能,但是会降低修改性能。当减少索引时,会提高修改性能,降低检索性能。因此,当修改操作远远多于检索操作时,不应该创建索引。可以基于数据库表中的单列或多列创建索引。多列索引可以区分其中一列可能有相同值的行。 如果经常同时搜索两列或多列或按两列或多列排序时,索引也很有帮助。例如,如果经常在同一查询中为姓和名两列设置判据,那么在这两列上创建多列索引将很有意义。 确定索引的有效性: 检查查询的WHERE和JOIN子句。在任一子句中包括的每一列都是索引可以选择的对象。 对新索引进行试验以检查它对运行查询性能的影响。 考虑已在表上创建的索引数量。最好避免在单个表上有很多索引。 检查已在表上创建的索引的定义。最好避免包含共享列的重叠索引。 检查某列中唯一数据值的数量,并将该数量与表中的行数进行比较。比较的结果就是该列的可选择性,这有助于确定该列是否适合建立索引,如果适合,确定索引的类型。根据数据库的功能,可以在数据库设计器中创建三种索引: 唯一索引、主键索引和聚集索引。有关数据库所支持的索引功能的详细信息,请参见数据库文档。 提示: 尽管唯一索引有助于定位信息,但为获得最佳性能结果,建议改用主键或唯一约束。 唯一索引 唯一索引是不允许其中任何两行具有相同索引值的索引。 当现有数据中存在重复的键值时,大多数数据库不允许将新创建的唯一索引与表一起保存。数据库还可能防止添加将在表中创建重复键值的新数据。例如,如果在employee表中职员的姓(lname)上创建了唯一索引,则任何两个员工都不能同姓。 主键索引 数据库表经常有一列或列组合,其值唯一标识表中的每一行。该列称为表的主键。 在数据库关系图中为表定义主键将自动创建主键索引,主键索引是唯一索引的特定类型。该索引要求主键中的每个值都唯一。当在查询中使用主键索引时,它还允许对数据的快速访问。 聚集索引 在聚集索引中,表中行的物理顺序与键值的逻辑 (索引) 顺序相同。一个表只能包含一个聚集索引。 如果某索引不是聚集索引,则表中行的物理顺序与键值的逻辑顺序不匹配。与非聚集索引相比,聚集索引通常提供更快的数据访问速度。 索引 uuid vs 自增 需要看你索引适应的形式,如果使用 b-tree 索引形式,有序 id 比无需 id 好,如果是 hash 索引,两个差别不大。主要原因是索引在磁盘上存储的形式,常用的 b-tree 索引如果 id 是连续的,那么数据存储在相邻的磁盘上,如果查询和写入操作的 id 连续,那么减少随机读写硬盘的几率,提升读写效率。所以看你的实际情况,如果你用的是 b-tree 索引,同时记录比较多,那么用有序 id 作为索引效率会高很多。 ...

Created 17176-11-17 · Updated 17176-11-17 · 1 min · 87 words · -

sql join

sql join 多个条件 SELECT a.* FROM product a LEFT JOIN product_details b ON a.id=b.id AND b.weight!=44 AND b.exist=0 WHERE b.id IS NULL; join inner join(等值连接) 只返回两个表中联结字段相等的行 left join (左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 INNER JOIN 语法: INNER JOIN 连接两个数据表的用法: SELECT * FROM 表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号 INNER JOIN 连接三个数据表的用法: SELECT * FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号 **INNER JOIN 连接四个数据表的用法: ** SELECT * FROM ((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号 ...

Created 14146-11-14 · Updated 14146-11-14 · 3 min · 429 words · -

悲观锁和乐观锁

悲观锁和乐观锁 为什么需要锁 (并发控制) ? 在多用户环境中,在同一时间可能会有多个用户更新相同的记录,这会产生冲突。这就是著名的并发性问题。 典型的冲突有: 丢失更新: 一个事务的更新覆盖了其它事务的更新结果,就是所谓的更新丢失。例如: 用户A把值从 6 改为 2, 用户B把值从 2 改为 6, 则用户 A 丢失了他的更新。 脏读: 当一个事务读取其它完成一半事务的记录时, 就会发生脏读取。例如: 用户 A, B 看到的值都是 6, 用户 B 把值改为 2, 用户 A 读到的值仍为 6。 为了解决这些并发带来的问题。 我们需要引入并发控制机制。 并发控制机制 最常用的处理多用户并发访问的方法是加锁。当一个用户锁住数据库中的某个对象时,其他用户就不能再访问该对象。加锁对并发访问的影响体现在锁的粒度上。比如,放在一个表上的锁限制对整个表的并发访问;放在数据页上的锁限制了对整个数据页的访问;放在行上的锁只限制对该行的并发访问。可见行锁粒度最小,并发访问最好,页锁粒度最大,表锁介于2者之间。 悲观锁 悲观锁在操作数据时比较悲观,认为别人会同时修改数据。因此操作数据时直接把数据锁住,直到操作完成后才会释放锁;上锁期间其他人不能修改数据。 假定会发生并发冲突,屏蔽一切可能违反数据完整性的操作。悲观锁假定其他用户企图访问或者改变你正在访问、更改的对象的概率是很高的,因此在悲观锁的环境中,在你开始改变此对象之前就将该对象锁住,并且直到你提交了所作的更改之后才释放锁。悲观的缺陷是不论是页锁还是行锁,加锁的时间可能会很长,这样可能会长时间的限制其他用户的访问,也就是说悲观锁的并发访问性不好。 乐观锁 乐观锁在操作数据时非常乐观,认为别人不会同时修改数据。因此乐观锁不会上锁,只是在执行更新的时候判断一下在此期间别人是否修改了数据: 如果别人修改了数据则放弃操作,否则执行操作。 假设不会发生并发冲突,只在提交操作时检查是否违反数据完整性。乐观锁不能解决脏读的问题。乐观锁则认为其他用户企图改变你正在更改的对象的概率是很小的,因此乐观锁直到你准备提交所作的更改时才将对象锁住,当你读取以及改变该对象时并不加锁。可见乐观锁加锁的时间要比悲观锁短,乐观锁可以用较大的锁粒度获得较好的并发访问性能。但是如果第二个用户恰好在第一个用户提交更改之前读取了该对象,那么当他完成了自己的更改进行提交时,数据库就会发现该对象已经变化了,这样,第二个用户不得不重新读取该对象并作出更改。这说明在乐观锁环境中,会增加并发用户读取对象的次数。 从数据库厂商的角度看,使用乐观的页锁是比较好的,尤其在影响很多行的批量操作中可以放比较少的锁,从而降低对资源的需求提高数据库的性能。再考虑聚集索引。在数据库中记录是按照聚集索引的物理顺序存放的。如果使用页锁,当两个用户同时访问更改位于同一数据页上的相邻两行时,其中一个用户必须等待另一个用户释放锁,这会明显地降低系统的性能。interbase和大多数关系数据库一样,采用的是乐观锁,而且读锁是共享的,写锁是排他的。可以在一个读锁上再放置读锁,但不能再放置写锁;你不能在写锁上再放置任何锁。锁是目前解决多用户并发访问的有效手段。 乐观锁应用 使用自增长的整数表示数据版本号。更新时检查版本号是否一致,比如数据库中数据版本为6,更新提交时version=6+1,使用该version值(=7)与数据库version+1(=7)作比较,如果相等,则可以更新,如果不等则有可能其他程序已更新该记录,所以返回错误。 使用时间戳来实现. 注: 对于以上两种方式,Hibernate自带实现方式: 在使用乐观锁的字段前加 annotation: @Version, Hibernate在更新时自动校验该字段。 java中的乐观锁基本都是通过CAS操作实现的 悲观锁应用 结论 在实际生产环境里边,如果并发量不大且不允许脏读,可以使用悲观锁解决并发问题;但如果系统的并发非常大的话,悲观锁定会带来非常大的性能问题,所以我们就要选择乐观锁定的方法. 参考文档 [1]Concurrent Control http://en.wikipedia.org/wiki/Concurrency_control [2] Oracle的悲观锁和乐观锁http://space.itpub.net/12158104/viewspace-374745 [3] timestamp应用——乐观锁和悲观锁【转】http://hi.baidu.com/piaokes/blog/item/9b0c6854e4909050564e00b3.html 事务隔离 https://www.cnblogs.com/kismetv/p/10787228.html http://www.cnblogs.com/Bob-FD/p/3352216.html ...

Created 1016-11-01 · Updated 1016-11-01 · 1 min · 71 words · lcf

sql command

sql command -- http://www.wiloon.com/?p=1899 insert into t1 values (1,'1',1) on duplicate key update c0=c0+1; INSERT INTO "表格名" ("栏位1", "栏位2", ...) VALUES ("值1", "值2", ...);

Created 29296-10-29 · Updated 29296-10-29 · 1 min · 24 words · lcf

细化解析 不同类型数据库的死锁问题

细化解析 不同类型数据库的死锁问题 论坛中有很多关于死锁问题的讨论,在理论方面,R.Ramakrishnan的《Database management systems》也有非常精辟的阐述。就实际开发而言,不同的数据库环境有着不同的处理方法,不同的体系架构也会导致不同的结果,下面来简单介绍一下不同类型数据库的死锁问题。 1.MSSQL、DB2、Oracle之类的现代DBMS或者中间件可以帮助我们自动解决绝大部分死锁,其余一部分难以处理的死锁则由DBA在数据库控制端手工处理。就应用程序而言,不需要在源代码级过多考虑地考虑死锁问题。 2.死锁的发生对系统的性能和吞吐量有着明显的影响,但只要存在针对共享数据资源的大规模并发访问的情况,那么死锁是不可避免的。 理论上,预防死锁的最好的途径是: 给每一个transaction设定一个优先级,同时确保较低优先级的事务不必等待较高优先级事务释放共享资源,反过来,也确保较高优先级的事务能够立刻取得相应的资源。如果开发人员无法判别事务的优先级,那么可以考虑在每个事务开始时赋予它一个的时间戳,依据时间戳的先后来判定事务的优先级,这类似于FIFO队列。在这方面,现代DBMS都提供了相应的语言支持。但是,假设由于网络故障而导致高优先级的事务无法commit或者rollback,那么是否其他低级别事务便要一直等待或者被抛弃?或者一个事务中的update操作施加了多个表级锁,并且占用了大量时间,那么即便这种事务从逻辑上并不合理,是否也要保持它的高优先级? 针对稀缺资源的竞争在任何场合都是正常的,死锁出现的因果关系给予我一个提示,就是不能盲目地依赖DBMS和DBA在死锁发生后再去解决死锁问题,那样必然已经对用户体验造成了消极影响。开发人员在设计过程中,需要更多地研判可能的并发访问问题。这些问题可能包括: 尽可能缩短事务。在同一DB中并发执行多个需要长时间运行的事务时,发生死锁的概率较大。事务运行时间越长,其持有exclusive锁或update锁的时间便越长,从而堵塞了其它活动并可能导致死锁。保持事务在一个批处理中,可以最小化事务的网络通信往返量,减少完成事务可能的延迟并释放锁。同时,涉及多个表的查询更新操作,若比较耗时,尽量不要放在一个事务内处理,能分割便分割。若不能分割,便尽可能使之在业务量较小的时间(例如子夜或者午餐时间)执行。 尽可能按同一顺序访问数据对象。如果所有并发事务按同一顺序访问对象,则发生死锁的可能性会降低。 避免编写包含用户交互的事务。因为运行没有用户交互的批处理的速度要远远快于用户手动响应查询的速度,若用户不能及时反馈,则此事务将挂起。因而将严重降低系统的吞吐量,因为事务持有的任何锁只有在事务提交或回滚时才会释放。即使不出现死锁的情况,访问同一资源的其它事务也会被阻塞,等待该事务完成。 使用低隔离级别。确定事务是否能在更低的隔离级别上运行。执行提交读允许事务读取另一个事务已读取 (未修改) 的数据,而不必等待第一个事务完成。使用较低的隔离级别 (例如提交读) 而不使用较高的隔离级别 (例如可串行读) 可以缩短持有共享锁的时间,从而降低了锁定争夺。 考虑体系结构的优化与代码重构,提高系统整体的运行效率。例如尽可能不要采用类似EJB的效率低下的计算模型,或者将复杂的业务置于编译存储过程中执行。 通过程序控制事务提交的时机。如果一次检索出了10万条记录但只更改了其中的100条,就可以通过代码来执行100个update。或是用分段提交,即所有的修改使用多个事务进行提交,但这样会使事务不完整,应酌情使用。 将经常更新的数据库和查询数据库分开。定期将不改变的数据导入查询数据库中,这样查询和更新就可以分开进行,而降低死锁机率。 在进行数据库模式设计时,注意外键引用的完整性,并对外键加索引。如果更新了父表的主键,由于外键上没有索引,所以子表会被锁定;如果删除了父表中的一行,整个子表也会被锁定。

Created 24246-10-24 · Updated 24246-10-24 · 1 min · 24 words · lcf

六个方法解决应用程序中死锁现象的出现

六个方法解决应用程序中死锁现象的出现 在应用程序中就可以采用下面的一些方法来避免死锁: (1) 合理安排表访问顺序。 (2) 在事务中尽量避免用户干预,尽量使一个事务处理的任务少些, 保持事务简短并在一个批处理中。 (3) 数据访问时域离散法, 数据访问时域离散法是指在客户机/服务器结构中,采取各种控制手段控制对数据库或数据库中的对象访问时间段。主要通过以下方式实现: 合理安排后台事务的执行时间,采用工作流对后台事务进行统一管理。工作流在管理任务时,一方面限制同一类任务的线程数 (往往限制为1个) ,防止资源过多占用; 另一方面合理安排不同任务执行时序、时间,尽量避免多个后台任务同时执行,另外, 避免在前台交易高峰时间运行后台任务。 (4) 数据存储空间离散法。数据存储空间离散法是指采取各种手段,将逻辑上在一个表中的数据分散到若干离散的空间上去,以便改善对表的访问性能。主要通过以下方法实现: 第一,将大表按行或列分解为若干小表; 第二,按不同的用户群分解。 (5) 使用尽可能低的隔离性级别。隔离性级别是指为保证数据库数据的完整性和一致性而使多用户事务隔离的程度,SQL92定义了4种隔离性级别: 未提交读、提交读、可重复读和可串行。如果选择过高的隔离性级别,如可串行,虽然系统可以因实现更好隔离性而更大程度上保证数据的完整性和一致性,但各事务间冲突而死锁的机会大大增加,大大影响了系统性能。 (6) 使用绑定连接, 绑定连接允许两个或多个事务连接共享事务和锁,而且任何一个事务连接要申请锁如同另外一个事务要申请锁一样,因此可以允许这些事务共享数据而不会有加锁的冲突。

Created 24246-10-24 · Updated 24246-10-24 · 1 min · 25 words · lcf

如何解决数据库中的死锁问题

如何解决数据库中的死锁问题 说道死锁问题的解决,一般情况下我们都是选择KILL进程,但如果不查出引起死锁的原因,死锁的现象则会频繁出现,其实只要通过查找引起死锁的操作,就可以方便的解决死锁。 **具体的解决方法如下: ** 1.再死锁发生时,我们可以通过下面的语法,查询到引起死锁的操作: use master go declare @spid int,@bl int DECLARE s_cur CURSOR FOR select 0 ,blocked from (select * from sysprocesses where blocked>0 ) a where not exists(select * from (select * from sysprocesses where blocked>0 ) b where a.blocked=spid) union select spid,blocked from sysprocesses where blocked>0 OPEN s_cur FETCH NEXT FROM s_cur INTO @spid,@bl WHILE @@FETCH_STATUS = 0 begin if @spid =0 select ‘引起数据库死锁的是: ‘+ CAST(@bl AS VARCHAR(10)) + ‘进程号,其执行的SQL语法如下’ ...

Created 24246-10-24 · Updated 24246-10-24 · 2 min · 220 words · lcf

sqlite 数据类型

sqlite 数据类型 一般数据采用的固定的静态数据类型,而 SQLite 采用的是动态数据类型,会根据存入值自动判断。SQLite 具有以下五种数据类型: NULL: 空值。 INTEGER: 带符号的整型,具体取决有存入数字的范围大小 REAL: 浮点数字,存储为8-byte IEEE浮点数 TEXT: 字符串文本 BLOB: 二进制对象 但实际上,sqlite3 也接受如下的数据类型: smallint 16 位元的整数 interger 32 位元的整数 decimal(p,s) p 精确值和 s 大小的十进位整数,精确值p是指全部有几个数(digits)大小值,s是指小数点後有几位数。如果没有特别指定,则系统会设为 p=5; s=0 。 float 32位元的实数。 double 64位元的实数。 char(n) n 长度的字串,n不能超过 254。 varchar(n) 长度不固定且其最大长度为 n 的字串,n 不能超过 4000。 graphic(n) 和 char(n) 一样,不过其单位是两个字元 double-bytes, n不能超过127。这个形态是为了支援两个字元长度的字体,例如中文字。 vargraphic(n) 可变长度且其最大长度为 n 的双字元字串,n不能超过 2000 date 包含了 年份、月份、日期。 time 包含了 小时、分钟、秒 timestamp 包含了 年、月、日、时、分、秒、千分之一秒 datetime DATETIME 类型用于存储日期和时间信息。它的格式通常是 “YYYY-MM-DD HH:MM:SS” ...

Created 8086-07-08 · Updated 8086-07-08 · 1 min · 134 words · -

adb shell sqlite DB

adb shell sqlite DB 在Android应用程序开发中,我们有时可能会用到系统中自带内嵌的数据库sqlite3,例如我们在某个应用程序中创建了数据库,如何查看该数据库或者如何查看该数据库中包含有哪些表或数据。下面是我在应用程序中创建了一个数据库以及表,如何采用命令行的方式去查看该数据库和表 cd /data/data/com.wiloon.android.rsslab/databases sqlite3 RssLab .tables select * from tag; com.wiloon.android.rsslab 是包名. RssLab 是数据库名. tag: 表名 .exit 退出. 查看字段名 .header on 查看sqlite3表结构的命令 在android下通过adb shell命令可以进入sqlite3的命令行client,见: 在android命令行下使用sqlite3。 如果想列出该数据库中的所有表,可: .table 如果想查看这些表的结构: select * from sqlite_master where type=“table”; 可以看到类似: 默认情况下,不会出现红框中的表头,需要之前设置,命令为: .header on 如果只想查看具体一张表的表结构,比如查看emperors表,命令为: select * from sqlite_master where type=“table” and name=“emperors”; 另外,也可以这样: sqlite> .schema emperors CREATE TABLE emperors( id integer primary key autoincrement, name text,dynasty text,start_year text); http://marshal.easymorse.com/index.html%3Fp=2981.html

Created 8086-07-08 · Updated 8086-07-08 · 1 min · 68 words · -

Database – DDL,DML,DCL,TCL

Database – DDL,DML,DCL,TCL DDL (Data Definition Language) 数据库定义语言statements are used to define the database structure or schema. DDL是SQL语言的四大功能之一。 用于定义数据库的三级结构,包括外模式、概念模式、内模式及其相互之间的映像,定义数据的完整性、安全控制等约束 DDL不需要commit. CREATE ALTER DROP TRUNCATE COMMENT RENAME DML (Data Manipulation Language) 数据操纵语言statements are used for managing data within schema objects. 由DBMS提供,用于让用户或程序员使用,实现对数据库中数据的操作。 DML分成交互型DML和嵌入型DML两类。 依据语言的级别,DML又可分成过程性DML和非过程性DML两种。 需要commit. SELECT INSERT UPDATE DELETE MERGE CALL EXPLAIN PLAN LOCK TABLE 3.DCL (Data Control Language) 数据库控制语言 授权,角色控制等 GRANT 授权 REVOKE 取消授权 4.TCL (Transaction Control Language) 事务控制语言 SAVEPOINT 设置保存点 ...

Created 1016-07-01 · Updated 1016-07-01 · 2 min · 400 words · -

SQL99

SQL99 来自ITwiki,开放的信息技术大百科 http://wiki.ccw.com.cn/SQL99 SQL99是数据库的一个ANSI/ISO标准。这个标准的前身是SQL92 ANSI/ISO标准,而SQL92之前还有一个SQL89 ANSI/ISO标准。它定义了一种语言 (SQL) 以及数据库的行为 (事务、隔离级别等) 。你知道许多商业数据库至少在某种程度上是符合SQL99的吗?不过,这对于查询和应用的可移植性没有多大的意义,这一点你也清楚吗? SQL92标准有4个层次: q 入门级 (Entry level) 。这是大多数开发商符合的级别。这一级只是对前一个标准SQL89稍做修改。所有数据库开发商都不会有更高的级别,实际上,美国国家标准和技术协会NIST (National Institute of Standards and Technology,这是一家专门检验SQL合规性的机构) 除了验证入门级外,甚至不做其他的验证。Oracle 7.0于1993年通过了NIST的SQL92入门级合规性验证,那时我也是小组中的一个成员。如果一个数据库符合入门级,它的特性集则是Oracle 7.0的一个功能子集。 q 过渡级。这一级在特性集方面大致介于入门级和中间级之间。 q 中间级。这一级增加了许多特性,包括 (以下所列并不完整) : n 动态SQL n 级联DELETE以保证引用完整性 n DATE和TIME数据类型 n 域 n 变长字符串 n CASE表达式 n 数据类型之间的CAST函数 q 完备级。增加了以下特性 (同样,这个列表也不完整) : n 连接管理 n BIT串数据类型 n 可延迟的完整性约束 n FROM子句中的导出表 n CHECK子句中的子查询 n 临时表 入门级标准不包括诸如外联结 (outer join) 、新的内联结 (inner join) 语法等特性。过渡级则指定了外联结语法和内联结语法。中间级增加了更多的特性,当然,完备级就是SQL92全部。有关SQL92的大多数书都没有区别这些级别,这就会带来混淆。这些书只是说明了一个完整实现SQL92的理论数据库会是什么样子。所以无论你拿起哪一本书,都无法将书中所学直接应用到任何SQL92数据库上。关键是,SQL92最多只达到入门级,如果你使用了中间级或更高级里的特性,就存在无法"移植"应用的风险。 SQL99只定义了两级一致性: 核心 (core) 一致性和增强 (enhanced) 一致性。SQL99力图远远超越传统的"SQL",并引入了一些对象—关系构造 (数组、集合等) 。它包括SQL MM (多媒体,multimedia) 类型、对象—关系类型等。还没有哪个开发商的数据库经认证符合SQL99核心级或增强级,实际上,据我所知,甚至没有哪个开发商声称他们的产品完全达到了某级一致性。 对于不同的数据库来说,SQL语法可能存在差异,实现有所不同,同一个查询在不同数据库中的性能也不一样,不仅如此,还存在并发控制、隔离级别、查询一致性等问题。我们将在第7章详细讨论这些问题,并介绍不同数据库的差异对你会有什么影响。 SQL92/SQL99试图对事务应如何工作以及隔离级别如何实现给出一个明确的定义,但最终,不同的数据库还是有不同的结果。这都是具体实现所致。在一个数据库中,某个应用可能会死锁并完全阻塞。但在另一个数据库中,同样是这个应用,这些问题却有可能不会发生,应用能平稳地运行。在一个数据库中,你可能利用了阻塞 (物理串行化) ,但在另一个数据库上部署时,由于这个数据库不会阻塞,你就会得到错误的答案。要将一个应用部署在另一个数据库上,需要花费大量的精力,付出艰辛的劳动,即使你100%地遵循标准也不例外。 关键是,不要害怕使用开发商特有的特性,毕竟,你为这些特性花了钱。每个数据库都有自己的一套"技巧",在每个数据库中总能找到一种完成操作的好办法。要使用最适合当前数据库的做法,移植到其他数据库时再重新实现。要使用合适的编程技术,从而与这些修改隔离,我把这称为防御式编程 (defensive programming) 。 取自"http://wiki.ccw.com.cn/SQL99"

Created 1016-07-01 · Updated 1016-07-01 · 1 min · 88 words · -