在缓存组定义中,有一些选项,它们平常很少会用到,但在一些特定的场合也许有用。
这些选项是:
* ON DELETE CASCADE
* UNIQUE HASH ON
* Where 条件中的SYNONYM
* 缓存LOB数据
on delete cascade由于涉及到delete操作,因此一般用于AWT缓存组。不过只读缓存组也可以用。
对于只读缓存组,在Oracle端可以不指定on delete cascade,而且可以没有主外键约束。在Oracle端删除root table的数据时,通过autorefresh反馈到timesten端,然后timesten执行on delete cascade。
CREATE TABLE customer
(cust_num NUMBER(6) NOT NULL PRIMARY KEY,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100));
CREATE TABLE orders
(ord_num NUMBER(10) NOT NULL PRIMARY KEY,
cust_num NUMBER(6) NOT NULL,
when_placed DATE NOT NULL,
when_shipped DATE NOT NULL);
insert into customer values ( 1, 'West', 'Frank Edwards', '100 Pine St. Portland OR' );
insert into customer values ( 2, 'East', 'Angela Wilkins', '356 Olive St. Boston MA' );
insert into customer values ( 3, 'Midwest', 'Stephen Johnson', '7638 Walker Dr. Chicago IL' );
INSERT INTO customer VALUES (4, 'East', 'Roberta Simon', '3667 Park Ave. New York NY');
INSERT INTO orders VALUES(1,1, DATE '2012-01-25', DATE '2012-01-30');
commit;
cacheadm>
CREATE READONLY CACHE GROUP customer_orders
FROM tthr.customer
(cust_num NUMBER(6) NOT NULL,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100),
PRIMARY KEY(cust_num)),
tthr.orders
(ord_num NUMBER(10) NOT NULL,
cust_num NUMBER(6) NOT NULL,
when_placed DATE NOT NULL,
when_shipped DATE NOT NULL,
PRIMARY KEY(ord_num),
FOREIGN KEY(cust_num) REFERENCES tthr.customer(cust_num) ON DELETE CASCADE);
cacheadm>load cache group customer_orders commit every 256 rows;
4 cache instances affected.
tthr>select * from customer;
< 1, West, Frank Edwards, 100 Pine St. Portland OR >
< 2, East, Angela Wilkins, 356 Olive St. Boston MA >
< 3, Midwest, Stephen Johnson, 7638 Walker Dr. Chicago IL >
< 4, East, Roberta Simon, 3667 Park Ave. New York NY >
4 rows found.
tthr>select * from orders;
< 1, 1, 2012-01-25 00:00:00, 2012-01-30 00:00:00 >
1 row found.
SQL> delete from customer where cust_num = 1;
1 row deleted.
SQL> commit;
Commit complete.
SQL> select * from orders;
ORD_NUM CUST_NUM WHEN_PLAC WHEN_SHIP
---------- ---------- --------- ---------
1 1 25-JAN-12 30-JAN-12
5分钟后,autorefresh生效,着急的话可以手工refresh一次。
tthr>select * from customer;
< 2, East, Angela Wilkins, 356 Olive St. Boston MA >
< 3, Midwest, Stephen Johnson, 7638 Walker Dr. Chicago IL >
< 4, East, Roberta Simon, 3667 Park Ave. New York NY >
3 rows found.
tthr>select * from orders; <- on delete cascade生效了
0 rows found.
不过此时Oracle与TimesTen的数据已经不一致了。
SQL> select * from orders;
ORD_NUM CUST_NUM WHEN_PLAC WHEN_SHIP
---------- ---------- --------- ---------
1 1 25-JAN-12 30-JAN-12
对于AWT缓存组,oracle端必须有匹配的主外键关系,必须指定on delete cascade。
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP customer_orders
FROM tthr.customer
(cust_num NUMBER(6) NOT NULL,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100),
PRIMARY KEY(cust_num)),
tthr.orders
(ord_num NUMBER(10) NOT NULL,
cust_num NUMBER(6) NOT NULL,
when_placed DATE NOT NULL,
when_shipped DATE NOT NULL,
PRIMARY KEY(ord_num),
FOREIGN KEY(cust_num) REFERENCES tthr.customer(cust_num) ON DELETE CASCADE);
cacheadm>CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP customer_orders
> FROM tthr.customer
> (cust_num NUMBER(6) NOT NULL,
> region VARCHAR2(10),
> name VARCHAR2(50),
> address VARCHAR2(100),
> PRIMARY KEY(cust_num)),
> tthr.orders
> (ord_num NUMBER(10) NOT NULL,
> cust_num NUMBER(6) NOT NULL,
> when_placed DATE NOT NULL,
> when_shipped DATE NOT NULL,
> PRIMARY KEY(ord_num),
> FOREIGN KEY(cust_num) REFERENCES tthr.customer(cust_num) ON DELETE CASCADE);
5164: No matching foreign key with cascade action for table TTHR.ORDERS on Oracle
The command failed.
SQL>
CREATE TABLE customer
(cust_num NUMBER(6) NOT NULL PRIMARY KEY,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100));
CREATE TABLE orders
(ord_num NUMBER(10) NOT NULL PRIMARY KEY,
cust_num NUMBER(6) NOT NULL,
when_placed DATE NOT NULL,
when_shipped DATE NOT NULL,
FOREIGN KEY(cust_num) REFERENCES customer(cust_num));
insert into customer values ( 1, 'West', 'Frank Edwards', '100 Pine St. Portland OR' );
insert into customer values ( 2, 'East', 'Angela Wilkins', '356 Olive St. Boston MA' );
insert into customer values ( 3, 'Midwest', 'Stephen Johnson', '7638 Walker Dr. Chicago IL' );
INSERT INTO customer VALUES (4, 'East', 'Roberta Simon', '3667 Park Ave. New York NY');
INSERT INTO orders VALUES(1,1, DATE '2012-01-25', DATE '2012-01-30');
commit;
cacheadm>
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP "CUSTOMER_ORDERS"
FROM
"TTHR"."CUSTOMER" (
"CUST_NUM" NUMBER(6) NOT NULL,
"REGION" VARCHAR2(10 BYTE) ,
"NAME" VARCHAR2(50 BYTE) ,
"ADDRESS" VARCHAR2(100 BYTE),
PRIMARY KEY("CUST_NUM")
),
"TTHR"."ORDERS" (
"ORD_NUM" NUMBER(10) NOT NULL,
"CUST_NUM" NUMBER(6) NOT NULL,
"WHEN_PLACED" DATE NOT NULL,
"WHEN_SHIPPED" DATE NOT NULL,
PRIMARY KEY("ORD_NUM"),
FOREIGN KEY("CUST_NUM")
REFERENCES "TTHR"."CUSTOMER"("CUST_NUM")
ON DELETE CASCADE
);
5164: No matching foreign key with cascade action for table TTHR.ORDERS on Oracle
The command failed.
CREATE TABLE customer
(cust_num NUMBER(6) NOT NULL PRIMARY KEY,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100));
CREATE TABLE orders
(ord_num NUMBER(10) NOT NULL PRIMARY KEY,
cust_num NUMBER(6) NOT NULL,
when_placed DATE NOT NULL,
when_shipped DATE NOT NULL,
FOREIGN KEY(cust_num) REFERENCES customer(cust_num) ON DELETE CASCADE);
cacheadm>
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP "CUSTOMER_ORDERS"
FROM
"TTHR"."CUSTOMER" (
"CUST_NUM" NUMBER(6) NOT NULL,
"REGION" VARCHAR2(10 BYTE) ,
"NAME" VARCHAR2(50 BYTE) ,
"ADDRESS" VARCHAR2(100 BYTE),
PRIMARY KEY("CUST_NUM")
),
"TTHR"."ORDERS" (
"ORD_NUM" NUMBER(10) NOT NULL,
"CUST_NUM" NUMBER(6) NOT NULL,
"WHEN_PLACED" DATE NOT NULL,
"WHEN_SHIPPED" DATE NOT NULL,
PRIMARY KEY("ORD_NUM"),
FOREIGN KEY("CUST_NUM")
REFERENCES "TTHR"."CUSTOMER"("CUST_NUM")
ON DELETE CASCADE
);
5188: An oracle index is required on foreign key TTHR.ORDERS(CUST_NUM).
The command failed.
SQL> create index idx1 on orders(cust_num);
Index created.
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP "CUSTOMER_ORDERS"
FROM
"TTHR"."CUSTOMER" (
"CUST_NUM" NUMBER(6) NOT NULL,
"REGION" VARCHAR2(10 BYTE) ,
"NAME" VARCHAR2(50 BYTE) ,
"ADDRESS" VARCHAR2(100 BYTE),
PRIMARY KEY("CUST_NUM")
),
"TTHR"."ORDERS" (
"ORD_NUM" NUMBER(10) NOT NULL,
"CUST_NUM" NUMBER(6) NOT NULL,
"WHEN_PLACED" DATE NOT NULL,
"WHEN_SHIPPED" DATE NOT NULL,
PRIMARY KEY("ORD_NUM"),
FOREIGN KEY("CUST_NUM")
REFERENCES "TTHR"."CUSTOMER"("CUST_NUM")
ON DELETE CASCADE
);
成功!
cacheadm>load cache group customer_orders commit every 256 rows;
4 cache instances affected.
tthr>select * from customer;
< 1, West, Frank Edwards, 100 Pine St. Portland OR >
< 2, East, Angela Wilkins, 356 Olive St. Boston MA >
< 3, Midwest, Stephen Johnson, 7638 Walker Dr. Chicago IL >
< 4, East, Roberta Simon, 3667 Park Ave. New York NY >
4 rows found.
tthr>delete from customer where cust_num = 1;
1 row deleted.
tthr>select * from orders;
0 rows found.
SQL> select * from orders;
no rows selected
SQL> select count(*) from customer;
COUNT(*)
----------
3
unique hash on 和索引相关
UNIQUE HASH ON specifies that a hash index rather than a range index is created on the primary key columns of the cache table.
TimesTen缺省的索引为range index,比较适合范围查询,而hash index适合于完全匹配查询。
是否使用unique hasn on取决于你的业务行为,即使用哪种查询更频繁些。
TimesTen的缓存组操作不能直接调用Oracle中的函数,但可以通过Synonym间接调用。
A user-defined PL/SQL function in the Oracle database can be invoked indirectly in a WHERE clause within a CREATE CACHE GROUP, LOAD CACHE GROUP, or REFRESH CACHE GROUP (for dynamic cache groups only) statement.
由于函数和Synonym都是定义在Oracle端,因此最常用于只读缓存组,以及AWT缓存组的带where条件的Load和Refresh操作。
SQL>
CREATE OR REPLACE FUNCTION get_customer_name
(c_num customer.cust_num%TYPE) RETURN VARCHAR2 IS
c_name customer.name%TYPE;
BEGIN
SELECT name INTO c_name FROM customer WHERE cust_num = c_num;
RETURN c_name;
END get_customer_name;
/
GRANT EXECUTE ON get_customer_name TO PUBLIC;
cacheadm>
CREATE READONLY CACHE GROUP top_customer
FROM tthr.customer
(cust_num NUMBER(6) NOT NULL,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100),
PRIMARY KEY(cust_num))
WHERE name = get_customer_name(100);
5221: Oracle syntax error in OCIStmtExecute(): ORA-00904: "GET_CUSTOMER_NAME": invalid identifier rc = -1
5117: Illegal WHERE clause for cache table TTHR.CUSTOMER
The command failed. <- 不能直接调用Oracle函数
SQL> CREATE PUBLIC SYNONYM retname FOR get_customer_name;
Synonym created.
cacheadm>
CREATE READONLY CACHE GROUP top_customer
FROM tthr.customer
(cust_num NUMBER(6) NOT NULL,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100),
PRIMARY KEY(cust_num))
WHERE name = retname(100); <- 通过Synonym调用函数成功
cacheadm>cachegroups;
Cache Group CACHEADM.TOP_CUSTOMER:
Cache Group Type: Read Only
Autorefresh: Yes
Autorefresh Mode: Incremental
Autorefresh State: Paused
Autorefresh Interval: 5 Minutes
Autorefresh Status: ok
Aging: No aging defined
Root Table: TTHR.CUSTOMER
Where Clause: name = retname(100)
Table Type: Read Only
1 cache group found.
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP top_customer
FROM tthr.customer
(cust_num NUMBER(6) NOT NULL,
region VARCHAR2(10),
name VARCHAR2(50),
address VARCHAR2(100),
PRIMARY KEY(cust_num))
WHERE name = retname(100);
cacheadm>CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP top_customer
> FROM tthr.customer
> (cust_num NUMBER(6) NOT NULL,
> region VARCHAR2(10),
> name VARCHAR2(50),
> address VARCHAR2(100),
> PRIMARY KEY(cust_num))
> WHERE name = retname(100);
8268: Asynchronous or Synchronous Writethrough cache group cannot have a WHERE clause
The command failed. <-读写缓存组不允许带where条件,但可以在load/refresh时带where条件。
CREATE ASYNCHRONOUS WRITETHROUGH CACHE GROUP "CUSTOMER_ORDERS"
FROM
"TTHR"."CUSTOMER" (
"CUST_NUM" NUMBER(6) NOT NULL,
"REGION" VARCHAR2(10 BYTE) ,
"NAME" VARCHAR2(50 BYTE) ,
"ADDRESS" VARCHAR2(100 BYTE),
PRIMARY KEY("CUST_NUM")
),
"TTHR"."ORDERS" (
"ORD_NUM" NUMBER(10) NOT NULL,
"CUST_NUM" NUMBER(6) NOT NULL,
"WHEN_PLACED" DATE NOT NULL,
"WHEN_SHIPPED" DATE NOT NULL,
PRIMARY KEY("ORD_NUM"),
FOREIGN KEY("CUST_NUM")
REFERENCES "TTHR"."CUSTOMER"("CUST_NUM")
);
cacheadm>load cache group customer_orders where customer.name = retname(100) commit every 256 rows;
0 cache instances affected. <-load时调用Synonym成功
SQL>
CREATE TABLE t (
i INT NOT NULL PRIMARY KEY
, c CLOB
, b BLOB
, nc NCLOB);
INSERT INTO t VALUES (1
, RPAD('abcdefg8', 2048, 'abcdefg8')
, HEXTORAW(RPAD('123456789ABCDEF8', 4000, '123456789ABCDEF8'))
, RPAD('abcdefg8', 2048, 'abcdefg8')
);
commit;
grant select on t to cacheadm;
grant delete, update, insert on t to cacheadm;
cacheadm>
CREATE DYNAMIC ASYNCHRONOUS WRITETHROUGH CACHE GROUP cg1
FROM tthr.t
(i INT NOT NULL PRIMARY KEY
, c CLOB
, b BLOB
, nc NCLOB);
5115: Unsupported type mapping for column
<-按照user guide中的做法是错的,是文档bug,改为以下通过
CREATE DYNAMIC ASYNCHRONOUS WRITETHROUGH CACHE GROUP cg1
FROM tthr.t
(i INT NOT NULL PRIMARY KEY
, c VARCHAR2(128)
, b VARBINARY(128)
, nc NVARCHAR2(128));