阳光男孩

Never give up!

Entries Tagged ‘数据库’

用Java实现数据库增删集合元素

1顶一下     Oracle数据库中增删集合元素的操作该如何实现呢?其实利用Java Function就可以轻松的实现,本文我们就主要介绍这一实现方法。   源程序如下:以下是代码片段:package zgdx.action; import java.math.BigDecimal;   import java.sql.Array;   //import java.sql.Connection;   import java.sql.DriverManager;   import java.sql.SQLException;   import java.util....[阅读全文]

1
顶一下

     Oracle数据库中增删集合元素的操作该如何实现呢?其实利用Java Function就可以轻松的实现,本文我们就主要介绍这一实现方法。
  源程序如下:以下是代码片段:package zgdx.action; import java.math.BigDecimal;
  import java.sql.Array;
  //import java.sql.Connection;
  import java.sql.DriverManager;
  import java.sql.SQLException;
  import java.util.ArrayList;
  import java.util.logging.Level;
  import java.util.logging.Logger;
  import oracle.jdbc.*;
  import oracle.sql.ARRAY;
  import oracle.sql.ArrayDescriptor; public class OraTools {
  static public Array addElementOfArray(ARRAY ary, Object e){
  try {
  Object[] bigs = null;
  if(ary==null) bigs = new Object[0];
  else bigs = (Object[]) ary.getArray();
  for(int i=0; i
  if(e.equals(bigs[i])){ return ary; }
  Object[] objs = new Object[bigs.length+1];
  for(int i=0; i
  objs[objs.length-1] = e;
  OracleConnection conn = (OracleConnection) DriverManager.getConnection(“jdbc:default:connection:”);
  //((OracleConnection)conn.unwrap(OracleConnection.class))
  //Array arr = conn.createARRAY(typeName.toUpperCase(), objs ); //11g r1
  Array arr = new ARRAY(ArrayDescriptor.createDescriptor( ary.getSQLTypeName(), conn), conn, objs);
  return arr;
  } catch (SQLException ex) {
  //Logger.getLogger(OraTools.class.getName())。log(Level.SEVERE, null, ex);
  System.err.println(“ERROR! addElementOfVarray: ” + ex.getMessage());
  return ary; } static public Array delElementOfArray(ARRAY ary, Object e){
  try {
  if( ary==null) return null;
  Object[] bigs = (Object[]) ary.getArray();
  ArrayList list = new ArrayList(bigs.length);
  for(int i=0; i
  if( ! e.equals(bigs[i])){ list.add(bigs[i]); }
  if(list.size()==bigs.length) return ary;
  Object[] objs = list.toArray();
  OracleConnection conn = (OracleConnection) DriverManager.getConnection(“jdbc:default:connection:”);
  //Array arr = conn.createARRAY(typeName.toUpperCase(), objs ); //11g r1
  Array arr = new ARRAY(ArrayDescriptor.createDescriptor(ary.getSQLTypeName(), conn), conn, objs);
  return arr;
  } catch (SQLException ex) {
  System.err.println(“ERROR! addElementOfVarray: ” + ex.getMessage());
  return ary; }
  }然后发布:loadjava -f -v -user username/passwd -r OraTools.java建call spec:以下是代码片段:CREATE OR REPLACE function addElementOfInt_nt(ary int_nt, dept_id NUMBER)
  return int_nt AS LANGUAGE JAVA NAME ‘zgdx.action.OraTools.addElementOfArray(java.sql.Array, java.lang.Object)
  return java.sql.Array’;测试:update test1 set cates = addElementOfInt_nt(cates, 10) where code=1;关于Oracle数据库中增删集合元素的Java Function的实现方法就介绍到这里了,希望本次的介绍能够对您有所帮助。

Leave a Comment

关系数据库的规范化

1顶一下一、函数依赖 在数据库中,函数依赖是最基本、最重要的一种依赖。 在数据库中,属性值之间会发生联系,这类联系称为函数依赖。 设有属性集U上的关系模式R(U),X,Y是U的子集,若对于任一个关系R中的任一元组在X中的属性值确定后,则在Y中的属性值必确定,则称Y依赖于X。 二、范式和规范化方法。 1 、第一范式(1NF) 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不...[阅读全文]

1
顶一下

一、函数依赖

在数据库中,函数依赖是最基本、最重要的一种依赖。
在数据库中,属性值之间会发生联系,这类联系称为函数依赖。
设有属性集U上的关系模式R(U),X,Y是U的子集,若对于任一个关系R中的任一元组在X中的属性值确定后,则在Y中的属性值必确定,则称Y依赖于X。
二、范式和规范化方法。
1 、第一范式(1NF)
在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库。  这体现了数据库的原子性;是不可再分的。
所谓第一范式(1NF)是指数据库表的每一列都是不可分割的基本数据项,同一列中不能有多个值,即实体中的某个属性不能有多个值或者不能有重复的属性。如果出现重复的属性,就可能需要定义一个新的实体,在第一范式(1NF)中表的每一行只包含一个实例的信息。例如,在学校的学生信息表中,每一行只表示一个学生的信息,一个学生的信息在表中只出现一次。简而言之,第一范式就是无重复的列。
2 、第二范式(2NF)  完全依赖于主键。
第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被惟一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。如图3-2 员工信息表中加上了员工编号(emp_id)列,因为每个员工的员工编号是惟一的,因此每个员工可以被惟一区分。这个惟一属性列被称为主关键字或主键、主码。
第二范式(2NF)要求每个非主属性完全依赖于主关键字。
所谓完全依赖是指不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体,新实体与原实体之间是一对多的关系。为实现区分通常需要为表加上一个列,以存储各个实例的惟一标识。简而言之,第二范式就是非主属性部分必须完全依赖于主关键字。
例如,把所有这些信息放到一个表中(学号,课程,学生姓名、年龄、性别、、课程学分、系别、学科成绩)下面存在如下的依赖关系。
关键字是:学号和课程
(学号)→ (姓名, 年龄,性别,系别)
(课程) → (学分)
(学号,课程)→ (学科成绩)
其属性之间的依赖关系如图所示:

在图中 ,虽然姓名, 年龄,性别,系别,成绩都依赖于学号,学分依赖于课程,但是他们都不是完全依赖于学号和课程,所以不是第二范式。
满足第二范式可以分解为三个模型。
如图:   图1:

图2:

图3 :

如上: 图1  图2   图3  都满足第二范式。
3 第三范式(3NF)
满足第三范式(3NF)必须先满足第二范式(2NF)。简而言之,第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。例如,存在一个部门信息表,其中每个部门有部门编号(dept_id)、部门名称、部门简介等信息。那么在图3-2的员工信息表中列出部门编号后就不能再将部门名称、部门简介等与部门有关的信息再加入员工信息表中。如果不存在部门信息表,则根据第三范式(3NF)也应该构建它,否则就会有大量的数据冗余。简而言之,第三范式就是属性不依赖于其它非主属性。

Comments (16)

MySQL数据库查询优化的3个好用方案

0顶一下此文章主要向大家描述的是三个好用的方法来对MySQL数据库查询进行优化,我们大家在实际操作中有时候会觉得MySQL数据库查询在某些应用 中好像有点“落伍”了,那么如何对其进行改造呢? 在优化查询中,数据库应用(如MySQL(和PHP搭配之最佳组合))即意味着对工具的操作与使用。使用索引、使用EXPLAIN分析查询以及 调整MySQL(和PHP搭配之最佳组合)的内部配置可达到优化查询的目的。 任何一位...[阅读全文]

0
顶一下

此文章主要向大家描述的是三个好用的方法来对MySQL数据库查询进行优化,我们大家在实际操作中有时候会觉得MySQL数据库查询在某些应用 中好像有点“落伍”了,那么如何对其进行改造呢?

在优化查询中,数据库应用(如MySQL(和PHP搭配之最佳组合))即意味着对工具的操作与使用。使用索引、使用EXPLAIN分析查询以及 调整MySQL(和PHP搭配之最佳组合)的内部配置可达到优化查询的目的。

任何一位数据库程序员都会有这样的体会:高通信量的数据库驱动程序中,一条糟糕的SQL查询语句可对整个应用程序的运行产生严重的影响,其不仅 消耗掉更多的数据库时间,且它将对其他应用组件产生影响。

如同其它学科,优化查询性能很大程度上决定于开发者的直觉。幸运的是,像MySQL(和PHP搭配之最佳组合)这样的数据库自带有一些协助工 具。本文简要讨论诸多工具之三种:使用索引,使用EXPLAIN分析查询以及调整MySQL(和PHP搭配之最佳组合)的内部配置。

1: 使用索引

MySQL(和PHP搭配之最佳组合)允许对数据库表进行索引,以此能迅速查找记录,而无需一开始就扫描整个表,由此显着地加快查询速度。每个 表最多可以做到16个索引,此外MySQL(和PHP搭配之最佳组合)还支持多列索引及全文检索。

给表添加一个索引非常简单,只需调用一个CREATE INDEX命令并为索引指定它的域即可。列表A给出了一个例子:

列表 A

1.MySQL(和PHP搭配之最佳组合)> CREATE INDEX idx_username ON users(username);

2.Query OK, 1 row affected (0.15 sec)

3.Records: 1 Duplicates: 0 Warnings: 0

这里,对users表的username域做索引,以确保在WHERE或者HAVING子句中引用这一域的SELECT查询语句运行速度比没有 添加索引时要快。通过SHOW INDEX命令可以查看索引已被创建(列表B)。

列表 B

1.MySQL(和PHP搭配之最佳组合)> SHOW INDEX FROM users;

2.————–+————-+———–+————-+———-+——–+——+————+———+

3.| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |

4.————–+————-+———–+————-+———-+——–+——+————+———+

5.| users | 1 | idx_username | 1 | username | A | NULL | NULL | NULL | YES | BTREE | |

6.————–+————-+———–+————-+———-+——–+——+————+———+

7.1 row in set (0.00 sec)

值得注意的是:索引就像一把双刃剑。对表的每一域做索引通常没有必要,且很可能导致运行速度减慢,因为向表中插入或修改数据时,MySQL(和 PHP搭配之最佳组合)不得不每次都为这些额外的工作重新建立索引。

另一方面,避免对表的每一域做索引同样不是一个非常好的主意,因为在提高插入记录的速度时,导致查询操作的速度减慢。这就需要找到一个平衡点, 比如在设计索引系统时,考虑表的主要功能(数据修复及编辑)不失为一种明智的选择。

2: 优化查询性能

在分析查询性能时,考虑EXPLAIN关键字同样很管用。EXPLAIN关键字一般放在SELECT查询语句的前面,用于描述MySQL(和 PHP搭配之最佳组合)如何执行查询操作、以及MySQL(和PHP搭配之最佳组合)成功返回结果集需要执行的行数。下面的一个简单例子可以说明(列表 C)这一过程:

列表 C

1.MySQL(和PHP搭配之最佳组合)> EXPLAIN SELECT city.name, city.district FROM city, country WHERE city.countrycode = country.code AND country.code = ‘IND’;

2.+—-+————-+———+——-+—————+———+———+——-+——+————-+

3.| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

4.+—-+————-+———+——-+—————+———+———+——-+——+————-+

| 1 | SIMPLE | country | const | Prima(最完善的虚拟主机管理系统)RY | Prima(最完善的虚拟主机管理系统)RY | 3 | const | 1 | Using index |

1.| 1 | SIMPLE | city | ALL | NULL | NULL | NULL | NULL | 4079 | Using where |

2.+—-+————-+———+——-+—————+———+———+——-+——+————-+

2 rows in set (0.00 sec)这里查询是基于两个表连接。EXPLAIN关键字描述了MySQL(和PHP搭配之最佳组合)是如何处理连接这两个表。必须清楚的是,当前设计要 求MySQL(和PHP搭配之最佳组合)处理的是country表中的一条记录以及city表中的整个4019条记录。这就意味着,还可使用其他的优化技 巧改进其查询方法。例如,给city表添加如下索引(列表D):

列表 D

1.MySQL(和PHP搭配之最佳组合)> CREATE INDEX idx_ccode ON city(countrycode);

2.Query OK, 4079 rows affected (0.15 sec)

3.Records: 4079 Duplicates: 0 Warnings: 0

现在,当我们重新使用EXPLAIN关键字进行查询时,我们可以看到一个显着的改进(列表E):

列表 E

1.MySQL(和PHP搭配之最佳组合)> EXPLAIN SELECT city.name, city.district FROM city, country WHERE city.countrycode = country.code AND country.code = ‘IND’;

2.+—-+————-+———+——-+—————+———–+———+——-+——+————-+

3.| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |

4.+—-+————-+———+——-+—————+———–+———+——-+——+————-+

5.| 1 | SIMPLE | country | const | Prima(最完善的虚拟主机管理系统)RY | Prima(最完善的虚拟主机管理系统)RY | 3 | const | 1 | Using index |

6.| 1 | SIMPLE | city | ref | idx_ccode | idx_ccode | 3 | const | 333 | Using where |

7.+—-+————-+———+——-+—————+———–+———+——-+——+————-+

8.2 rows in set (0.01 sec)

在这个例子中,MySQL(和PHP搭配之最佳组合)现在只需要扫描city表中的333条记录就可产生一个结果集,其扫描记录数几乎减少了 90%!自然,数据库资源的查询速度更快,效率更高。

3: 调整内部变量

MySQL(和PHP搭配之最佳组合)是如此的开放,所以可轻松地进一步调整其缺省设置以获得更优的性能及稳定性。需要优化的一些关键变量如 下:

改变索引缓冲区长度(key_buffer)

一般,该变量控制缓冲区的长度在处理索引表(读/写操作)时使用。MySQL(和PHP搭配之最佳组合)使用手册指出该变量可以不断增加以确保 索引表的最佳性能,并推荐使用与系统内存25%的大小作为该变量的值。这是MySQL(和PHP搭配之最佳组合)十分重要的配置变量之一,如果你对优化和 提高系统性能有兴趣,可以从改变key_buffer_size变量的值开始。

改变表长(read_buffer_size)

当一个查询不断地扫描某一个表,MySQL(和PHP搭配之最佳组合)会为它分配一段内存缓冲区。read_buffer_size变量控制这 一缓冲区的大小。如果你认为连续扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能。

设定打开表的数目的最大值(table_cache)

该变量控制MySQL(和PHP搭配之最佳组合)在任何时候打开表的最大数目,由此能控制服务器响应输入请求的能力。它跟max_connections变量密切相关,增加table_cache值可 使MySQL(和PHP搭配之最佳组合)打开更多的表,就如增加max_connections值可增加连接数一样。当收到大量不同数据库及表的请求时, 可以考虑改变这一值的大小。

对缓长查询设定一个时间限制(long_query_time)

MySQL(和PHP搭配之最佳组合)带有“慢查询日志”,它会自动地记录所有的在一个特定的时间范围内尚未结束的查询。这个日志对于跟踪那些 低效率或者行为不端的查询以及寻找优化对象都非常有用。long_query_time变量控制这一最大时间限定,以秒为单位。

以上讨论并给出用于分析和优化SQL查询的三种工具的使用方法,以此提高你的应用程序性能。使用它们快乐地优化吧!

Comments (5)

数据库活动监控系列之:SQL注入攻击

0顶一下         如果你每天访问的网站需要登录,那么你的登录用户名和密码很可能是保存在关系数据库中,其他网站用户的登录信息也和你一起保存在数据库中,但愿你的密码保存前经过加密处理,如果是明文存储的话简直太可怕了。   不幸的是,有一些网站存在安全漏洞,攻击者可以通过一种叫做SQL注入的攻击技术窃取到存储在数据库中的密码信息。   更令人担忧的是,即使数据库打上所有...[阅读全文]

0
顶一下

         如果你每天访问的网站需要登录,那么你的登录用户名和密码很可能是保存在关系数据库中,其他网站用户的登录信息也和你一起保存在数据库中,但愿你的密码保存前经过加密处理,如果是明文存储的话简直太可怕了。

  不幸的是,有一些网站存在安全漏洞,攻击者可以通过一种叫做SQL注入的攻击技术窃取到存储在数据库中的密码信息。

  更令人担忧的是,即使数据库打上所有补丁也不能避免这种攻击,这不是一个补丁问题,更多的与数据库工作方式及系统设计有关。

  这种攻击可以针对任何包含来自数据库的数据的网页,如一个搜索页面,客户意见反馈页面,不管数据库是MySQL,SQL Server还是Oracle,都无法避免这种攻击,SQL注入攻击不仅是针对SQL Server的。

  通常,在数据库中使用一个表来存储用户登录信息,这个表至少有两列,一列存储用户名(username),另一列存储密码(password),而表名通常会被取为users或类似的名字。

  当用户在网站上提交他们的详细信息时,数据库将会解析username和password,然后转换为SQL字符串,发送给数据库,数据库引擎接收到的SQL类似:

SELECT * FROM users WHERE username = ‘fredsmith’ AND password = ‘userspassword’
  
  这是一个非常标准的SQL语句,无论你使用什么数据库存储用户的数据,SQL语句看起来都大同小异。

  攻击者对SQL注入攻击非常有兴趣,因为他们通过发送一些伪造数据就可以操纵数据库,如传入一个无效用户名:

SELECT * FROM users WHERE username = ‘ ‘ ‘ AND password = ‘ ‘

 

  攻击者提供一个单引号字符作为用户名,一个空格作为密码,数据库也表现得非常好,遇到这种查询就返回一个错误消息,但攻击者看到返回的错误消息后,不会就此罢手,而是要深入挖掘可利用的信息,可能一不小心数据库就暴露了表结构,这正是攻击者想要得到的东西,经验丰富的攻击者可以迅速地入侵数据库。

  在接下来的例子中,通过向username添加其它字符串来进一步欺骗数据库,例如,如果我们输入or email=’345作为用户名,查询解析器将会解析为:

SELECT * FROM users

  WHERE username = ‘ ‘ or email=’345 ‘ AND password = ‘ ‘

 

  如果数据库users表中不存在email列,它可能会爆出一个错误,另一方面,它可能无法给出错误消息暗示缺少一列email,我们需要做的是给用户输入一个email地址,由于大多数机构都有一个标准的电子邮件地址结构,因此很容易得到员工的名字,然后使用这个名字作为SQL注入时的用户名。

  正如你所看到的,从用户登录页面就可以很容易地构造出数据库结构,有时通过猜测也可以得到数据库结构。

  好消息是,保护数据库避免SQL注入也完全是可能的。常见的措施包括过滤用户输入,Cookie和URL中的单引号、双引号、斜线、反斜线和分号等特殊字符,此外,数字值先转换成整数再传递给数据库。

  另一方面,数据库活动监控解决方案通常会保护Web应用程序,处于学习模式的数据库活动监控工具会自动学习应用程序的“正常”活动,学习完后就知道哪些活动是正常的,因此攻击者伪造的查询就会被诊断为可疑活动,遇到这种行为,数据库活动监控工具就会产生一个警告,并采取适当的行动阻止非正常活动。

  良好的系统设计是防止SQL注入的重要方法,但和数据库活动监控工具结合使用,你将会更加放心。

Comments (295)