Oracle将统计信息和信息存储为关键/值的最佳实践

时间:2014-04-13 10:15:10

标签: sql oracle jpa oracle11g

问题:我有一个包含大量表和条目的庞大数据库。我的应用程序类似于社交网络,在我的数据库中,我有关于用户登录,用户手机型号,注册数据的信息...查看的页面数量,评论数量,回复...每个信息和用户活动有日期时间参考。我有一个用于管理我的用户的Web应用程序,我想要包含一个统计页面。在这个统计页面中,我想显示一些数据:

  • 登录了多少用户
  • 过去7天内注册了多少用户
  • 多少Android VS iOS
  • ...

我正面临着如何从数据库中检索所有这些信息的问题。拥有JPA级别并使用实体,是否可以创建特殊的View 统计作为键/值:

   Key      Value
   TotUser   200
   Android   100
   iOS       100
   NewUser    10

简单示例:

CREATE TABLE peoples 
    (
 id number(38), 
 name varchar(20), 
 os varchar(10)
 );

INSERT INTO peoples
(id, name, os)
VALUES
(1,'john', 'Android');

INSERT INTO peoples
(id, name, os)
VALUES
(2,'jane', 'iOS');

有没有办法将我的查询存储在VIEW或其他对象中?

select count(*) from peoples; // as TotUser
select count(*) from peoples where os like 'Android'; // as Android
select count(*) from peoples where os like 'iOS'; // as iOS

并有一个STATISTIC表,其中键/值是我查询的结果?

   STATISTIC
   ---------------
   Key      Value
   ---------------
   TotUser   2
   Android   1
   iOS       1

我做了什么: 现在我创建了一个对象Statistic,我执行每个查询并在对象Statistic中存储信息,提供一个键名。有没有办法通过SQL完成所有这些,避免在我的Java应用程序中对我的查询进行任何修改?存储过程?报告功能?

3 个答案:

答案 0 :(得分:2)

听起来你需要的是materialized view

我建议您按照自己选择的时间间隔按需刷新创建mviews。

您有两种方法可以通过materizlized视图实现目标

  1. 使用union all创建一个大型mview来收集所有统计信息。
  2. 为每个源表创建几个小mviews,并为一个主要的MVIEW创建连接所有源视图。

答案 1 :(得分:1)

这可以通过单个SQL语句和表的单次扫描来完成,除非变得太慢,否则不需要做任何复杂的事情,在这种情况下,MV可能就是答案。

with all_cts as (
select os, count(*) as ct
  from peoples
 group by os
       )
select 'TotUser' as key, sum(ct) as value
  from all_cts
 union all
select *
  from all_cts

利用sub-query factoring一次查询表格,并有效地创建一个微小的内存表,然后可以使用两次。

如果您需要查询单个操作系统,您可以只运行查询或创建此查询作为视图并使用WHERE子句查询视图:

select * from my_view_with_everything where os = 'Android';

答案 2 :(得分:0)

感谢haki建议,我通过为每个统计信息使用单独的视图和连接所有统计信息的全局主视图解决​​了我的问题:

CREATE TABLE peoples 
    (
 id number(38), 
 name varchar(20), 
 os varchar(10)
 );


INSERT INTO peoples
(id, name, os)
VALUES
(1,'john', 'Android');

INSERT INTO peoples
(id, name, os)
VALUES
(2,'jane', 'iOS');

CREATE VIEW Stat(key,value) AS
SELECT 
'Total registered users', count(*) from peoples;

CREATE VIEW StatA(key,value) AS
SELECT 
'Total users using Android', count(*) from peoples where os like 'Android';

CREATE VIEW StatI(key,value) AS
SELECT 
'Total users using iOS', count(*) from peoples where os like 'iOS';

CREATE VIEW StatTot(key,value) AS
SELECT key,value FROM Stat
UNION ALL
SELECT key,value FROM StatA
UNION ALL
SELECT key,value FROM StatI;

StatTot输出:select * from StatTot

    KEY           VALUE
Total registered users  2
Total users using Android   1
Total users using iOS   1

SQLFiddle

通过使用此解决方案,我可以在运行时添加新的自定义统计信息并显示它们,而无需修改我的Web应用程序。