| JohnBull 回复于:2003-01-30 23:39:48
|
“外部关键字”我估计是(Foreign key),应该翻译成“外键约束”。
PostgreSQL并没有按SQL标准实现外建约束,而是通过其特有的规则系统来实现的。
|
| ecloud 回复于:2003-02-08 01:06:02
|
7.2以后好像支持外键了?
|
| redfox 回复于:2003-02-09 21:06:52
|
一句老话:尺有所短,寸有所长~
|
| shixl 回复于:2003-03-04 16:58:14
|
当创建一个引用关系时候,会在引用表上自动创建一个触发器,当向这个引用表插入修改数据时候,由这个触发器去查询被引用表。以此来知道是否违反了约束。
/*-------------------------------------------------------------------------
*
* trigger.c
* PostgreSQL TRIGGERs support code.
*
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql-server/src/backend/commands/trigger.c,v 1.136 2002/10/21 19:55:49 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "catalog/catalog.h"
#include "catalog/catname.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "catalog/pg_language.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_trigger.h"
#include "catalog/pg_type.h"
#include "commands/defrem.h"
#include "commands/trigger.h"
#include "executor/executor.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "parser/parse_func.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/inval.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"
static void InsertTrigger(TriggerDesc *trigdesc, Trigger *trigger, int indx);
static HeapTuple GetTupleForTrigger(EState *estate,
ResultRelInfo *relinfo,
ItemPointer tid,
TupleTableSlot **newSlot);
static HeapTuple ExecCallTriggerFunc(TriggerData *trigdata,
FmgrInfo *finfo,
MemoryContext per_tuple_context);
static void DeferredTriggerSaveEvent(ResultRelInfo *relinfo, int event,
HeapTuple oldtup, HeapTuple newtup);
static void DeferredTriggerExecute(DeferredTriggerEvent event, int itemno,
Relation rel, TriggerDesc *trigdesc, FmgrInfo *finfo,
MemoryContext per_tuple_context);
/*
* Create a trigger. Returns the OID of the created trigger.
*
* forConstraint, if true, says that this trigger is being created to
* implement a constraint. The caller will then be expected to make
* a pg_depend entry linking the trigger to that constraint (and thereby
* to the owning relation(s)).
*/
[color=red:df016f36da]/* 创建触发器
第一个参数是语法树结构
第二个是是否是约束触发器
*/[/color:df016f36da]
Oid
CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
{
int16 tgtype;
int16 tgattr[FUNC_MAX_ARGS];
Datum values[Natts_pg_trigger];
char nulls[Natts_pg_trigger];
Relation rel;
AclResult aclresult;
Relation tgrel;
SysScanDesc tgscan;
ScanKeyData key;
Relation pgrel;
HeapTuple tuple;
Oid fargtypes[FUNC_MAX_ARGS];
Oid funcoid;
Oid funcrettype;
Oid trigoid;
int found = 0;
int i;
char constrtrigname[NAMEDATALEN];
char *trigname;
char *constrname;
Oid constrrelid = InvalidOid;
ObjectAddress myself,
referenced;
rel = heap_openrv(stmt->relation, AccessExclusiveLock);
if (stmt->constrrel != NULL)
constrrelid = RangeVarGetRelid(stmt->constrrel, false);
[color=red:df016f36da]
/*判断是否一个约束触发器 */
[/color:df016f36da]else if (stmt->isconstraint)
{
/*
* If this trigger is a constraint (and a foreign key one)
* then we really need a constrrelid. Since we don't have one,
* we'll try to generate one from the argument information.
*
* This is really just a workaround for a long-ago pg_dump bug
* that omitted the FROM clause in dumped CREATE CONSTRAINT TRIGGER
* commands. We don't want to bomb out completely here if we can't
* determine the correct relation, because that would prevent loading
* the dump file. Instead, NOTICE here and ERROR in the trigger.
*/
bool needconstrrelid = false;
void *elem = NULL;
/* 那么起一个特定规则的名字 */
if (strncmp(strVal(llast(stmt->funcname)), "RI_FKey_check_", 14) == 0)
{
/* A trigger on FK table. */
needconstrrelid = true;
if (length(stmt->args) > RI_PK_RELNAME_ARGNO)
elem = nth(RI_PK_RELNAME_ARGNO, stmt->args);
}
else if (strncmp(strVal(llast(stmt->funcname)), "RI_FKey_", 8) == 0)
{
/* A trigger on PK table. */
needconstrrelid = true;
if (length(stmt->args) > RI_FK_RELNAME_ARGNO)
elem = nth(RI_FK_RELNAME_ARGNO, stmt->args);
}
if (elem != NULL)
{
RangeVar *rel = makeRangeVar(NULL, strVal(elem));
constrrelid = RangeVarGetRelid(rel, true);
}
if (needconstrrelid && constrrelid == InvalidOid)
elog(NOTICE, "Unable to find table for constraint \"%s\"",
stmt->trigname);
}
if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "CreateTrigger: relation \"%s\" is not a table",
stmt->relation->relname);
if (!allowSystemTableMods && IsSystemRelation(rel))
elog(ERROR, "CreateTrigger: can't create trigger for system relation %s",
stmt->relation->relname);
/* permission checks */
if (stmt->isconstraint)
{
/* foreign key constraint trigger */
/* 进行权限检查 */
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_REFERENCES);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, RelationGetRelationName(rel));
if (constrrelid != InvalidOid)
{
aclresult = pg_class_aclcheck(constrrelid, GetUserId(), ACL_REFERENCES);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, get_rel_name(constrrelid));
}
}
else
{
/* real trigger */
aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), ACL_TRIGGER);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, RelationGetRelationName(rel));
}[color=#444444:df016f36da][/color:df016f36da]
|
| netkiller 回复于:2003-03-08 14:13:57
|
这遍文章没意义。
PostgreSQL vs Mysql不是一个档次上的东西。比什么。。
如同Oracle 与 Mysql对比。。
PostgreSQL 是关系型数据库的鼻祖。是Infomix前身。它与Ms sql server,sybase,infomix 是一个档次。
mysql与access ,foxbase一个档次。。
为什么这么说。
mysql 与 foxbase的功能差不多。。只提供数据的读,存。如:视图,触发器,过程,序列。subselect 。外键。。。。它都不支持。
只支持select ,update,insert,drop,delete....... 这些功能Access都有。且Access还支持外键,视图。比 mysql功能多。
|
| 夜猫子 回复于:2003-03-08 15:02:40
|
虽然我很高兴听到有人这么说(窃喜),不过因为这两个东西的比较是很多初学者感兴趣的,所以干脆就收一篇放在这里。
|
| eapass 回复于:2003-03-11 02:47:14
|
[quote:13627008ab="netkiller"]这遍文章没意义。
PostgreSQL vs Mysql不是一个档次上的东西。比什么。。
如同Oracle 与 Mysql对比。。
PostgreSQL 是关系型数据库的鼻祖。是Infomix前身。它与Ms sql server,sybase,infomix 是一个档次。
mysq..........[/quote:13627008ab]
谢谢,你的回复使我对PostgreSQL vs Mysql有点感觉了,谢谢.
|
| redfox 回复于:2003-03-13 00:46:28
|
这不是档次的问题,是定位的问题。
好比微软的word和记事本,word的功能很强,不过大多数情况我们还是在用记事本,why?简单的web应用,我去用视图,触发器,过程干吗?
要知道:当我们在获得了应用要求的功能后,速度和易用性才是第一位的。
PostgreSQL支持的太全了,我只会在复杂,并且同步性要求很高的的BS结构的项目里用它,或者只是在几个特定的模块中。
|
| 红袖添香 回复于:2003-03-18 08:13:43
|
[quote:882e8d0289="redfox"]这不是档次的问题,是定位的问题。
好比微软的word和记事本,word的功能很强,不过大多数情况我们还是在用记事本,why?简单的web应用,我去用视图,触发器,过程干吗?
要知道:当我们在获得了应用要求的功?.........[/quote:882e8d0289]
很有道理的说~~
|
| netkiller 回复于:2003-03-18 22:39:46
|
楼上朋友。首先你真正用过事务处理的数据器吗?
你没用过,自然不知,外键,触发器,视图.....有多方便.
drop table taba;
create table taba(
id integer,
name varchar(50)
);
insert into taba values(1,'chen');
insert into taba values(2,'chen');
insert into taba values(3,'chen');
insert into taba values(4,'chen');
insert into taba values(5,'chen');
insert into taba values(6,'chen');
insert into taba values(7,'chen');
select * from taba;
drop table tabb;
create table tabb(
id integer,
name varchar(50)
);
insert into tabb values(1,'chen');
insert into tabb values(2,'chen');
insert into tabb values(3,'chen');
insert into tabb values(4,'chen');
insert into tabb values(5,'chen');
insert into tabb values(6,'chen');
insert into tabb values(7,'chen');
select * from tabb;
drop function delete_tab ();
CREATE FUNCTION delete_tab () RETURNS opaque AS '
-- DECLARE
BEGIN
Delete from tabb where id = OLD.id;
RETURN NEW;
END;
' LANGUAGE 'plpgsql';
drop TRIGGER delete_tri on taba;
CREATE TRIGGER delete_tri
BEFORE Delete
ON taba FOR EACH ROW
EXECUTE PROCEDURE delete_tab ();
delete from taba where id = 2;
select * from tabb;
当表taba 中删除一条数据中。tabb中的数据同时被删除。
如果是MYSQL你得在程序中用两条SQL实现。
delete from taba where id = 2;
delete from tabb where id = 2;
view 可以省去你在读表时烦琐。
pgsql:select * from view where id =1
mysq:select t1.id,t2.uid,t3.name,t4.pass,t5.email from t1,t2,t3,t4,t5 where t1.id=1 and t2.id=1 and
t3.id =1 and t4.id =1 and t5.id =1
过程,函数。
adduse(integer,integer)
begin
insert into user values($1,$2);
......
end;
exec adduser('user1','passwd');
事务
begin
step 1
step 2
...
step 10
commit;
如果任何一步出错。事务被取消,即。去银行取¥。
1插卡
2密码
4取多少¥¥¥
5在帐号里扣除¥
6出钱
7退卡
如果没有事务处理。5出错。你的¥没了。6没出来¥。7退卡。你再一看。卡里原5000¥现在成了2000¥。银行不诚认。你自己哭吧。
这种环境MySQL不行。
外键。没有外键参考。插入,删除的数据可能不一至。
不多说了。。自己想想吧。
|
| 红袖添香 回复于:2003-03-18 22:53:25
|
...
我想 redfox 老大说得很清楚了,对于简单网页应用,他不需要;对于复杂、并且同步性要求很高的的BS结构中会用到。
就象 ChinaUnix.net 偶而出现 phpBB: Critical Error 虽然很烦人,但不会象银行帐户问题那么严重。再极端一点,Oracle 很强,但是我需不需要用它来处理我的通讯录呢?Oh no, thanks! 我想一个 EXCEL 或是 Gnumeric 就能满足我的要求了。
我认为,他的说法很有道理 —— 不是档次问题而是定位问题。
|
| jxbbs 回复于:2003-03-19 00:04:16
|
要用就用最好的,最牛B的,这样才不算菜鸟啊!:-)
|
| redfox 回复于:2003-03-19 00:05:37
|
其实很多事情都是这样。
我们总是在寻找所谓“最好的”,倒还不如好好考虑一下什么才是“最合适的”。
|
| wolfop 回复于:2003-03-19 21:28:52
|
说实在,MYSQL已经支持外件了,至于触发器,我们再生产系统中的INFORMIX都不用这个东西。
|
| wangrujun 回复于:2003-04-01 09:09:45
|
[quote:5f5ecf50df="wolfop"]说实在,MYSQL已经支持外件了,至于触发器,我们再生产系统中的INFORMIX都不用这个东西。[/quote:5f5ecf50df]
不用触发器的生产系统,或者你的系统太小,或者你的构架不好。
|
| netkiller 回复于:2003-04-01 12:00:26
|
回楼上。。
因为你是程序员,不是DBA。。
我认为你对数据的认识,比对FOXBASE认识多不了多少。。
目前国内的项目人员。都对数据库认识不足。这些项目人员,之前都是程序员。。。干到30岁做就项目经理。。
这些人,给它Oracle。他的用法与MySQL一样,外建VIEW全不用。
只用select,insert ,update OK了,就可以做项目了。CRM,ERP,OA,。。。。。。
我在深圳干了三年,换了不少公司。大到几百人,小到三五人。。都一样很少公司有专业的DBA。
|
| gadfly 回复于:2003-04-01 12:25:06
|
[quote:7ac9ad096d="netkiller"]
因为你是程序员,不是DBA。。
我认为你对数据的认识,比对FOXBASE认识多不了多少。。
目前国内的项目人员。都对数据库认识不足。这些项目人员,之前都是程序员。。。干到30岁做就项目经理。。
这些人,给它Oracle。他的用法与MySQL一样,外建VIEW全不用。
只用select,insert ,update OK了,就可以做项目了。CRM,ERP,OA,。。。。。。
我在深圳干了三年,换了不少公司。大到几百人,小到三五人。。都一样很少公司有专业的DBA。
[/quote:7ac9ad096d]
同意你的观点,这也是国内项目开发流程不完善和不规范造成的,很多人都是身兼多职,虽然能锻炼能力,但是也造成角色的非专业化.
不过是否通过触发器还是通过应用来维护表数据间的逻辑关系,我觉得并不是绝对的,各有各的优缺点.
|
| wolfop 回复于:2003-04-01 17:09:29
|
[quote:02802f4577="wangrujun"]
不用触发器的生产系统,或者你的系统太小,或者你的构架不好。[/quote:02802f4577]
得了吧,少吹了。不是系统太小,而是系统太大,我用4台PC SERVER支持600万用户的系统,谁敢乱用触发器。要上的新系统倒是两台690,不过数据库容量20T,而且不是DSS,OLTP和批处理混和,你用触发器看看。
|
| wolfop 回复于:2003-04-01 17:17:48
|
[quote:18a62263ab="netkiller"]回楼上。。
因为你是程序员,不是DBA。。
我认为你对数据的认识,比对FOXBASE认识多不了多少。。
目前国内的项目人员。都对数据库认识不足。这些项目人员,之前都是程序员。。。干到30岁做就项目经理。。
这些人..........[/quote:18a62263ab]
呵呵,只能说你刚道比只会用FOXBASE的人层次高一点。知道触发器,VIEW的方便性,接触过多大的系统,而且是资金有限的系统。用VIEW 用触发器如何,我知道的系统,两台满配置15K,触发器、VIEW都用,可是系统的数据量和业务量都比我们用4台PC Server的要少,怎么了,崩溃的频繁程度还有反应速度等指标都比我不用触发器的要慢。一个DBMS+应用的设计,不是看是否用VIEW、是否用外键、是否用触发器衡量的,尤其对我这种甲方的人来说,我只关心系统的稳定性、反应时间和处理能力。
因此,不论黑猫白猫,抓道耗子就是好猫。
|
| netkiller 回复于:2003-04-01 21:09:50
|
回楼上。。
你是程序员吗?还是DBA?
不知你对数据库认识有多少。如果你真的用过Informix,你就不会再用MYSQL了。
有些环境MYSQL是不行。你是不是只做一些B/S,web页一类的开发。。
不知你接触过。银行,超市,证券,数据统计,大量数据分析。。。没。
如果你不想花¥¥¥买商业数据。PostgreSQL是最好的选译。。
还有你不要听信网上的对PostgreSQL与MYSQL的评论。。它们一般是做个程序来循环,读,写数据库。而不是对数据库事处比较。如果这样比下去。
任何数据都会失给MYSQL。Oracle是最慢的。
如果比事务处理能力。Oracle,PostgreSQL,SQL Server,SyBase....它们都可以在一个过程中执行一批SQL指令。而不是MYSQL那样。每次执行一条SQL并而每次都要与数据连接一次,关闭一次。
|
| netkiller 回复于:2003-04-01 21:55:23
|
呀!才发现。都到第二页了。我发完没看到结果。就以为没发出去。
所以发了很多重负的。。不家原量。。
不用触发器的生产系统,或者你的系统太小,或者你的构架不好。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
得了吧,少吹了。不是系统太小,而是系统太大,我用4台PC SERVER支持600万用户的系统,谁敢乱用触发器。要上的新系统倒是两台690,不过数据库容量20T,而且不是DSS,OLTP和批处理混和,你用触发器看看。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
20T,不用OLTP,不用DSS,确实是“你的构架不好”
这么大的系统为什么不用集群,和HA?????
对大家不要为了触发器,VIEW吵了。 我在上文提到触发器是因为在PostgreSQL里。它可以触发一个过程。PGSQL里触发器不像Oracle可以单独用。
我是想让大家尽量在数据库中处理,反回结果集。而不是在程序读出后再在程序中处理。不要把数据当成只能读记录的表。一些高级应用,多用一些。
楼上的朋友20T的数据库我想能不能给大家介绍一下管理经验,你不用触发器,不用VIEW,不用游标,不用序例。。。。。
你只用select ,insert,update,delete......你是如何管理的。。。。
不用游标。你每次select 都要检索20T的数据。。是如何做到的。。
记得我有一次去客户那,好奇想看看从没见过那么大的数据量,select * from tabe where date = 某年,计时,天那足足有两三个小时才处理完。
|
| wolfop 回复于:2003-04-01 22:52:00
|
[quote:67f2a0ec01="netkiller"]呀!才发现。都到第二页了。我发完没看到结果。就以为没发出去。
所以发了很多重负的。。不家原量。。
不用触发器的生产系统,或者你的系统太小,或者你的构架不好。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
?..........[/quote:67f2a0ec01]
真不知道你是再装白痴还是真白痴,我无非强调一个数据库系统+应用设计的好坏不是只看是否使用视图和触发器,你到好,好像我说了游标也不许用。另外你看的懂中文吗,我说不是DSS,而是OLTP和批处理混和。另外你是否知道库的大小和表的大小的区别?一个应用系统数据库容量20T,就意味着我一个表20T。
得了吧,你用过多大的系统,设计过多大的应用,吹牛前先考虑考虑自己又多少份量。HA能够提供系统的反应时间么?看你就是没有入门的,我说了我没有用HA么?你瞎猜什么。OPENSOURCE的数据库你玩过多少,要说POSTGRESQL是比MYSQL在SQL标准支持上面强,可以作为大系统应用,他和SAPDB的差劲有多大你知道么。
|
| wolfop 回复于:2003-04-01 22:54:09
|
[quote:9dcb835df4="netkiller"]回楼上。。
你是程序员吗?还是DBA?
不知你对数据库认识有多少。如果你真的用过Informix,你就不会再用MYSQL了。
有些环境MYSQL是不行。你是不是只做一些B/S,web页一类的开发。。
不知你接触过。银行,超市?..........[/quote:9dcb835df4]
我现在就在用INFORMIX,这个20T的系统也是用INFORMIX,可是在某些情况下我还是会用MYSQL,一些只需要简单查询的系统,我用INFORMIX干什么。要对付一个1T的这样的数据库用INFORMIX需要什么样的配置,我用MYSQL一台两年前淘汰的NETFINITY就可以了。我倒是怀疑你才见过多大的应用就充老大。
另外你的胡说八道实在的可笑到了极点,什么时候MYSQL需要执行一条SQL语句就需要连接一次关闭一次了,你的论据来自造谣么?
至于有事务的测试,在上次一次网上营业的测试中,ORACLE是第一,而MYSQL是第二,你自己去查询一下GOOGLE吧。当然MYSQL到现在为止恐怕还不能完成TPC-C测试。
|
| netkiller 回复于:2003-04-02 01:14:13
|
回楼上。to wolfop
呀!才发现。都到第二页了。我发完没看到结果。就以为没发出去。
所以发了很多重负的。。不家原量。。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
些贴之前:我看到的是你第一页最后一贴。没看到你后来的贴。。。。回贴与是回的第一页最后一贴。
“说实在,MYSQL已经支持外件了,至于触发器,我们再生产系统中的INFORMIX都不用这个东西。”
所以我的回复时我没看到结果。就很了很多次。也改了很多次。所以每行里都有
“回楼上。。
因为你是程序员,不是DBA。。
”
另请,在公共场所注意形像,言语。
另外你是否知道库的大小和表的大小的区别?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
:(不mount数据,能操作表吗?
你用过多大的系统
^^^^^^^^^^^^^^^^^^
做过商场,各种报表,图表(直方图,饼图,折线图)都是B/S结构,客户的需求。
数据多少T我不知,数据从1990--2002年,每日都有几千到几万条记录都可以查到 (其中一部分早期数据是FOXPRO导到ORACLE中的用于分析)
那时我拿到了它们的所有数据库资料。看了人家写的过程,触发器,视图……………………自叹不如。
他们的系统全是SUN的。管理是telnet登录后运行一个程序实现的。很多操作如(计算,分析,汇总等等。。。)都是在数据库中完成,通过PL/SQL。大量的使用过程,视图,触发器。select 操作都是通过视图进行。。。。
我在工作中发现。连接池如果使用不当。ORACLE常常用尽内存。我对连接池优化一下,但不管是如何优化,数据并发是一定的。比如1000就是1000,在优化也不可能超过1000,
所以我的经验就是能在数据中完成的工作不在应用程序中完成,程序多连接一次数据,1000-1,就会有一个用户连不上。我于是将要多次连接取值的操作,合并,写成一个数据库过程。
我的经验:
我现在,用pgsql 做项目。。
目前是
Form ==> jsp ==> javaBean ==> jdbc(pgsql or class12.zip) ==>
如果是select 用view来做,并格式化如to_char()。
如果是删除记录并涉及外键。就用触发器去删除外键的表。。 如果用程序完成。要执行多条SQL
如果是大量查找分析就用select func() 过程来做。然后反回结果集。
如果是一些特定的操作,一条SQL无法完成,也用过程例:adduser(varchar,varchar),deluser(integer id).......ext
目前还没用到游标。。
总之用最少的连接做大量的处理。尽量在数中完成操作。能用数据库的不用程序做。。。。。。。
什么时候MYSQL需要执行一条SQL语句就需要连接一次关闭一次了,你的论据来自造谣么?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
B/S下的开发。你可以去看
public getlist(){
db.connect();
try{
rs = executeQxxy("select ...x.x.x..x.x");
while(rs.next){
rs.getString(xxxx);
...
}
catch(xxxxx e){
e.xxx.x.x.x.();
}
fainly{
db.close();
}
}
类似这个。。如果你不关。一会数据连接池就玩完。。。。
ORACLE是第一,而MYSQL是第二
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
你也可以到GOOGLE上找找。。看看谁第一,谁第二。。。
论据是不是来自造谣么?我不知。。测试方都是权威公司。搞的。。
最后:
谈谈你们做什么应用。。你的经验。。
|
| wangrujun 回复于:2003-04-02 09:31:59
|
[quote:58436d50d8="wolfop"]
得了吧,少吹了。不是系统太小,而是系统太大,我用4台PC SERVER支持600万用户的系统,谁敢乱用触发器。要上的新系统倒是两台690,不过数据库容量20T,而且不是DSS,OLTP和批处理混和,你用触发器看看。[/quote:58436d50d8]
确实如您所说,触发器会影响效率,所以在触发器里面做什么工作是需要特别注意的。而且oracle的触发器功能非常强,如果不注意使用,确实会使用系统出问题。
主要问题是,在触发器里面做什么工作。触发器应该处理最密集应用的n%以内的代码。
代码最终还是要运行的,不同的就是在什么时间什么地点运行。分析、优化和决策,就是DBA的工作。您的说法,完全否定了触发器在大型数据库里面的应用,我认为未免偏颇。
而且您说,系统是在PC SERVER上跑。我的经验是oracle在64位的环境下才能有最大发挥
另外关于表的大小的问题。oracle既提供了一些对表的存储优化的功能,也提供对表的分割优化的功能。能管理20T的数据,您也是专业的DBA了。这些工作您一定也会做。不过您告诉我您是4个pc server,而不是告诉我您有磁盘数量、速度,内存容量、速度,这让我感到很不理解。另外如果对运算有要求,就应该告诉我您的PC server的OS以及CPU的数量
当然您对触发器的谨慎是有道理的,我支持谨慎使用触发器的观点。
|
| netkiller 回复于:2003-04-02 09:51:10
|
re: wangrujun
同意
不过我工作中用的最多是过程,不管什么技术,只要合理使用就行。
再问一下wolfop 你用什么牌子的PC SERVER?用什么操作系统?
我以前用联想,RAID5。。。做ORACLE数据服务器,常常崩溃原因是联想的硬件太差。双CPU的服务器运行一段时间(几个月到半年)不是其中一块CPU不工作,就是1000内存数据成了256,要不就是RAID 模块上的硬盘掉盘。 解决方法,开机箱,按一按CPU。内存拔下来。在插上去,RAID rebuild.....
搞死人啊。。。。
你的PC是什么牌的。
|
| wolfop 回复于:2003-04-02 11:56:59
|
[quote:aff7db6b28="wangrujun"]
确实如您所说,触发器会影响效率,所以在触发器里面做什么工作是需要特别注意的。而且oracle的触发器功能非常强,如果不注意使用,确实会使用系统出问题。
主要问题是,在触发器里面做什么工作。触发器应该处?..........[/quote:aff7db6b28]
那个用4台PC SERVER用的是INFORMIX,不是ORACLE。对于触发器是否在大型数据库应用中使用,这个和应用的特点密切相关,我没有完全否定,但是我绝对要强调一个系统设计的好坏应该看其运行效果(比如相应时间、DSS的决策时间、系统可用性、可扩展性等等),而不是本末倒置,将是否使用VIEW、 触发器、SP作为唯一的标准。另外我说的很清楚了,那个20T的数据库是用的两台690,不是PC SERVER。在这里不用触发器的原因很简单,如果在触发器实现业务逻辑,我们的应用特点在于业务逻辑相当复杂,触发器的伪编译特性导致会消耗DB SERVER上太多CPU资源,我还有6台660作为应用服务器,当然要尽量将逻辑放到应用服务器上面。
PCSERVER运行的数据库数量没有这么大,数据量在200G左右,提供给600万用户服务,至于一些配置细节,我觉得属于商业机密,一般我不打算细说,可以透露的就是这些机器是2000年能买到最高档的PC Server的半配。
|
| gadfly 回复于:2003-04-02 15:26:26
|
[quote:f085b7412e="netkiller"]
总之用最少的连接做大量的处理。尽量在数中完成操作。能用数据库的不用程序做。。。。。。。
[/quote:f085b7412e]
不同意这种观点,虽然存储过程和触发器有种种好处,但是逻辑过程全部依赖于它实现,是有问题的:
1、如果逻辑全部在存储过程中实现,那么涉及广泛业务逻辑和处理的应用程序可能会给服务器带来过重负荷。这类处理包括数据传输、数据遍历、数据转换和大计算量操作。应把这类处理移到业务或数据逻辑层中,与数据库服务器相比,它们具有更好的可缩放性。
2. 不要把所有业务逻辑都放在存储过程中。如果必须修改业务逻辑,应用程序的维护和灵活性将成为问题。例如,支持多个 RDBMS 的 ISV 应用程序不应当分别为每个系统维护存储过程。
3.通常,存储过程的编写与维护是一项专门技能,并非所有开发人员都能够掌握。这会造成项目开发计划的瓶颈。
http://www.yesky.com/20021112/1639500_2.shtml
总之,大的系统中,并不能过多的依赖于存储过程来完成业务和数据逻辑层该做的事情
|
| netkiller 回复于:2003-04-02 16:08:24
|
我看了你的给的
http://www.yesky.com/20021112/1639500_2.shtml
配合使用数据访问逻辑组件与存储过程
可以使用存储过程执行数据访问逻辑组件支持的许多数据访问任务。
优点
1.存储过程通常可以改善性能,因为数据库能够优化存储过程使用的数据访问计划并为以后的重新使用缓存该计划。
2,可以在数据库内分别设置各个存储过程的安全保护。管理员可以授予客户端执行某个存储过程的权限,而不授予任何基础表访问权限。
3,存储过程可以简化维护,因为修改存储过程通常比修改所部署的组件中的硬编码 SQL 语句要容易。然而,随着在存储过程中实现的业务逻辑的增多,上述优势会逐渐减弱。
4,存储过程增大了从基础数据库架构进行抽象的程度。存储过程的客户端与存储过程的实现细节和基础架构是彼此分离的。
存储过程会降低网络流量。应用程序可以按批执行 SQL 语句而不必发出多个 SQL 请求。
5,尽管存储过程具有上述优点,但仍有某些情况不适合使用存储过程。
缺点
1,如果逻辑全部在存储过程中实现,那么涉及广泛业务逻辑和处理的应用程序可能会给服务器带来过重负荷。这类处理包括数据传输、数据遍历、
数据转换和大计算量操作。应把这类处理移到业务过程或数据访问逻辑组件中,与数据库服务器相比,它们具有更好的可缩放性。
2,不要把所有业务逻辑都放在存储过程中。如果必须在 T - SQL 中修改业务逻辑,应用程序的维护和灵活性将成为问题。例如,支持多个 RDBMS 的 ISV 应用程序不应当分别为每个系统维护存储过程。
3,通常,存储过程的编写与维护是一项专门技能,并非所有开发人员都能够掌握。这会造成项目开发计划的瓶颈。
它是用ADO.net举例了。。。我没用过不好评论。
JavaBean EJB到是懂一些。
只要合里使用,应该没问题。太依赖程序也不好,如果是C/S结构,要改一动一下程序,就得编译。然后全公司都要装一遍。(只是个例子,现实中可能很少遇到)
如果用EJB技术 。数据访问逻辑组件部署在Application Server 上,这样做好些。如果数据访问逻辑组件全放在client端 处理我不支持。。。
|
| gadfly 回复于:2003-04-02 18:01:13
|
这个在N tier中,分层和设计的思想都是相同的,与框架无关。
虽然这篇文章是以.net举例的,但是用在j2ee中是一样的。
N tier中,数据逻辑和业务逻辑当然是在服务端实现的。你这个client指针对
数据库而言吧?
我的感觉是业务和数据逻辑可能是多变的,如果太依赖于存储过程,并不利于组件的维护,尤其是对于支持多数据库的产品。
至于上面说的性能问题,我想这种情况也是存在的,这类耗CPU资源的本来可以通过应用服务器来解决,但是用存储过程却会占用有限的数据库服务器的资源。
|
| spirit 回复于:2005-05-09 22:57:22
|
一群sb
|
| ecloud 回复于:2005-07-06 15:08:25
|
在标准的J2EE体系中,所有的商业逻辑必须封装成EJB或者助手类,也可以把某个数据结构(数据库中的一张表或者一个视图)抽象成实体Bean,因此在这种严格的OO设计中,是要尽量避免在数据库中处理任何逻辑的
至于C/S结构的设计来说,在DBM中封装一些商业逻辑是有益的
|
| ecloud 回复于:2005-07-06 15:11:50
|
另外补充一下,在中国,DBA不要妄想从Programer那里拿到商业逻辑代码的维护权
因此,商业逻辑不可能封装在DBM里
|
| littleboywj 回复于:2005-07-08 23:45:17
|
[quote:d021eff703="spirit"]一群sb[/quote:d021eff703]
那不知你是个什么DX??!!!!!
|
| dragon76 回复于:2005-07-14 10:46:26
|
[quote:0758b4a5fc="spirit"]一群sb[/quote:0758b4a5fc]
像你这样的DX,都不配叫人,还是有多远的滚多远的好
|
| snowpy 回复于:2005-07-16 12:51:49
|
真的是无知者无畏, 事务处理和外健/触发器之类的有什么联系?
你先把什么是ROLLBACK和ROLLFORWARD搞懂再说吧
[quote:1d570492a9="netkiller"]楼上朋友。首先你真正用过事务处理的数据器吗?
你没用过,自然不知,外键,触发器,视图.....有多方便.
drop table taba;
create table taba(
id integer,
name varchar(50)
);
insert into taba values(1..........[/quote:1d570492a9]
|
| snowpy 回复于:2005-07-16 12:57:21
|
越说越离谱, 什么每次MYSQL操作要与数据库连接和关闭一次???你要是懂连接池和数据库接口是什么概念就不会说出这么SB的东西.
银行和金融不用MYSQL是有他们特殊的原因, 但是并不等于MYSQL就是垃圾,
两年前的MYSQL就已经有基于IMDB的版本了, 把MYSQL和ACCESS列为一类的人我还算是第一次见识, 居然还是版主...希望已经是两年后的你有所长进
[quote:c83f3dd2af="netkiller"]回楼上。。
你是程序员吗?还是DBA?
不知你对数据库认识有多少。如果你真的用过Informix,你就不会再用MYSQL了。
有些环境MYSQL是不行。你是不是只做一些B/S,web页一类的开发。。
不知你接触过。银行,超市?.........[/quote:c83f3dd2af]
|
| snowpy 回复于:2005-07-16 13:07:56
|
你真的要比较的话, 我出国前在国内某电信公司工作, 一般做的项目都有20/30台SUN E4500/10000的服务器, 计费跑ORACLE,某些小项目跑MYSQL, 每天单单北京节点就有1300万的计费记录生成插入ORACLE(我写的oci+pro*c程序+schema+trigger+plsql procedure)
现在在北美某大型IT公司工作, 现在做的项目200台SUN服务器和几十台POSTGRESQL.
多年UNIX C++分布式系统开发经验, ORACLE 9I DBA管理员证书.
就我的经验觉得你实在不适合做版主的职位. POSTGRE确实不错, 但是并没有像你说的比MYSQL强那么多的地步, 每种产品都有自己的定位和市场.
希望你以后不要再误导初学者.
[quote:5db4e8e781="netkiller"]回楼上。to wolfop
呀!才发现。都到第二页了。我发完没看到结果。就以为没发出去。
所以发了很多重负的。。不家原量。。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
些贴之前:我看到的是你第一页最后一..........[/quote:5db4e8e781]
|
| cellar 回复于:2005-07-19 09:32:10
|
汗,长见识啊......真是强中自有强中手啊,在CU谁也不要托大...我的签名档有我的联系方法,很想和各位学习一下有关应用分布的问题,请高人能指教一下,谢谢
|
| jsean 回复于:2005-08-06 22:24:48
|
靠!啥人都有。
|