从 Oracle/Mysql 中的通用数据创建[物化]视图
我有一个包含 3 个表的通用数据模型,
CREATE TABLE Properties
(
propertyId int(11) NOT NULL AUTO_INCREMENT,
name varchar(80) NOT NULL
)
CREATE TABLE Customers
(
customerId int(11) NOT NULL AUTO_INCREMENT,
customerName varchar(80) NOT NULL
)
CREATE TABLE PropertyValues
(
propertyId int(11) NOT NULL,
customerId int(11) NOT NULL,
value varchar(80) NOT NULL
)
INSERT INTO Properties VALUES (1, 'Age');
INSERT INTO Properties VALUES (2, 'Weight');
INSERT INTO Customers VALUES (1, 'Bob');
INSERT INTO Customers VALUES (2, 'Tom');
INSERT INTO PropertyValues VALUES (1, 1, '34');
INSERT INTO PropertyValues VALUES (2, 1, '80KG');
INSERT INTO PropertyValues VALUES (1, 2, '24');
INSERT INTO PropertyValues VALUES (2, 2, '53KG');
我想做的是创建一个视图,该视图将属性中的所有行作为列,并将客户中的条目作为行。列值由 PropertyValues 填充。 例如
customerId Age Weight
1 34 80KG
2 24 53KG
我想我需要一个存储过程来执行此操作,也许还需要一个物化视图(“属性”表中的条目很少更改)。 有什么建议吗?
I have a generic datamodel with 3 tables
CREATE TABLE Properties
(
propertyId int(11) NOT NULL AUTO_INCREMENT,
name varchar(80) NOT NULL
)
CREATE TABLE Customers
(
customerId int(11) NOT NULL AUTO_INCREMENT,
customerName varchar(80) NOT NULL
)
CREATE TABLE PropertyValues
(
propertyId int(11) NOT NULL,
customerId int(11) NOT NULL,
value varchar(80) NOT NULL
)
INSERT INTO Properties VALUES (1, 'Age');
INSERT INTO Properties VALUES (2, 'Weight');
INSERT INTO Customers VALUES (1, 'Bob');
INSERT INTO Customers VALUES (2, 'Tom');
INSERT INTO PropertyValues VALUES (1, 1, '34');
INSERT INTO PropertyValues VALUES (2, 1, '80KG');
INSERT INTO PropertyValues VALUES (1, 2, '24');
INSERT INTO PropertyValues VALUES (2, 2, '53KG');
What I would like to do is create a view that has as columns all the ROWS in Properties and has as rows the entries in Customers. The column values are populated from PropertyValues.
e.g.
customerId Age Weight
1 34 80KG
2 24 53KG
I'm thinking I need a stored procedure to do this and perhaps a materialised view (the entries in the table "Properties" change rarely).
Any tips?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用动态 SQL 生成视图非常容易:
工作原理如下:
让我们创建一个新属性并为某些客户插入值......
问题是,属性将会发生变化,我猜你不会监督这种情况何时发生。所以你会发现它非常困难将更改应用于物化视图很重要,因为更改物化视图的投影需要删除它,因此在不中断服务的情况下执行此操作非常困难,但中断几乎是这样。如果
您确实想将视图语句转换为物化视图,请注意,Oracle 在物化视图方面似乎不喜欢 ANSI-92 语法(它抛出 ORA-12054)。应该是这样,但是当我更改为较旧的连接技术时,问题就消失了,这很烦人,因为外部连接语法比较笨重。
无需重新创建数据库对象的解决方案是在函数中使用动态 SQL。返回一个引用游标,它映射到 JDBC 结果集:
这将始终返回最新的投影:
现在,如果我们添加一个新属性,它会立即被拾取:
It's easy enough to generate a view with dynamic SQL:
Here's it working:
Let's create a new property and insert values for it for some of the customers...
The problem is, Properties are going to change, and I'm guessing you will have no oversight of when that happens. So you are going to find it very hard to apply the changes to a materialized view. This matters because changing the projection of a materialized view necessitates dropping it. So it's quite difficult to do this without an interruption to service. A similar consideration applies to the regular view , but the outage is almost zero.
If you do want to convert the view statement into a materialized view note that Oracle doesn't seem to like the ANSI-92 syntax when it comes to materialized views (it hurls ORA-12054). I'm not sure why that should be, but the problem went away when I changed to the older joining technique, which is annoying because the outer join syntax is clunkier.
A solution without the need to re-create database objects would be to use the dynamic SQL in a function which returns a Ref Cursor, which maps to a JDBC ResultSet:
This will always return the latest projection:
Now, if we add a new property it gets picked up immediately: