一. PowerDesigner创建表
打开PowerDesigner,然后点击File-->New Model然后选择如下图所示的物理数据模型
然后点击Columns,如下图设置,灰常简单,需要注意的就是P(primary主键) , F (foreign key外键) , M(mandatory强制性的,代表不可为空) 这三个,多看几遍理解其意思。
下面介绍一下物理模型导出SQL语句(点击Database按钮的Generate Database或者按ctrl+G)
打开之后如图所示,修改好存在sql语句的位置和生成文件的名称即可
逆向工程导出ORACLE数据库 表+字段+注释
选定一个编辑的表,右键- >Properties- >Columns- >Customize Columns and Filter(或直接用快捷键Ctrl+U)- >Comment(前面打勾)- >OK
二. SQL中的in与not in、exists与not exists的区别以及性能分析
1. in和exists
in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询,一直以来认为exists比in效率高的说法是不准确的。如果查询的两个表大小相当,那么用in和exists差别不大;如果两个表中一个较小一个较大,则子查询表大的用exists,子查询表小的用in;
例如:表A(小表),表B(大表)
select * from A where cc in(select cc from B) -->效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) -->效率高,用到了B表上cc列的索引。
相反的:
select * from B where cc in(select cc from A) -->效率高,用到了B表上cc列的索引
select * from B where exists(select cc from A where cc=B.cc) -->效率低,用到了A表上cc列的索引。
2. not in 和not exists
not in 逻辑上不完全等同于not exists,如果你误用了not in,小心你的程序存在致命的BUG,请看下面的例子:
create table #t1(c1 int,c2 int);
create table #t2(c1 int,c2 int);
insert into #t1 values(1,2);
insert into #t1 values(1,3);
insert into #t2 values(1,2);
insert into #t2 values(1,null);
select * from #t1 where c2 not in(select c2 from #t2); -->执行结果:无
select * from #t1 where c2 not exists(select * from #t2 where #t2.c2=#t1.c2) -->执行结果:1 3
正如所看到的,not in出现了不期望的结果集,存在逻辑错误。如果看一下上述两个select 语句的执行计划,也会不同,后者使用了hash_aj,所以,请尽量不要使用not in(它会调用子查询),而尽量使用not exists(它会调用关联子查询)。如果子查询中返回的任意一条记录含有空值,则查询将不返回任何记录。如果子查询字段有非空限制,这时可以使用not in,并且可以通过提示让它用hasg_aj或merge_aj连接。
如果查询语句使用了not in,那么对内外表都进行全表扫描,没有用到索引;而not exists的子查询依然能用到表上的索引。所以无论哪个表大,用not exists都比not in 要快。
三. Vue接口调用
//森林草原灭火-灭火作战次数走势
getFireFightingStatistics(data){
return request({
url: "/v1/command/getFireFightingStatistics",
method: "get",
params: data
})
},
引入api
编写方法
async getSingleLineChartsData(conditon) {
try {
let resp = await GlassTaskApi.getFireFightingStatistics(conditon)
let result = resp.data.result
let data = {
name: "灭火作战次数走势",
xData: [],
yData: []
}
result.forEach(e => {
data.xData.push(e.NAME)
data.yData.push(e.VALUE)
})
this.mhzzcszs = data
} catch (e) {
console.error(e)
}
},
四. 如何使用start with connect by prior递归用法
为了能更好的介绍如何使用,首先需要创建一个测试表,然后结合例子来说明
create table t_menu
( menu_id varchar2(32),
parent_id varchar2(32));
insert into t_menu values ( '1', '' );
insert into t_menu values ( '2', '1' );
insert into t_menu values ( '3', '1' );
insert into t_menu values ( '4', '2' );
insert into t_menu values ( '5', '3' );
insert into t_menu values ( '6', '4' );
commit;
select * from t_menu;
创建了t_menu表,然后插入几条数据,再查询出表里数据
再来看下创建的表结构,为了简单,这里就只有两个字段,menu_id和parent_id
start with
递归查询起始条件
connect by
连接语句,后面加上连接的条件
为了演示向上和向下两个方向,我们这里选择menu_id为4的中间节点作为起始节点。
SELECT
t.menu_id,
t.parent_id,
level
FROM
t_menu t
START WITH
t.menu_id = '4'
CONNECT BY
t.parent_id = PRIOR t.menu_id;
这里注意下PRIOR
的位置,和menu_id放一起,表示向下查询
SELECT
t.menu_id,
t.parent_id,
level
FROM
t_menu t
START WITH
t.menu_id = '4'
CONNECT BY
PRIOR t.parent_id = t.menu_id;
这里PRIOR
和parent_id放一起,表示按照父节点方向,向上查询
SELECT
t.menu_id,
t.parent_id,
level
FROM
t_menu t
START WITH
t.parent_id = '4'
CONNECT BY
PRIOR t.parent_id = t.menu_id;
START WITH
后面的起始条件,换成parent_id,则可以从结果中看出,level为1级的则以parent_id字段为条件做为起始节点
以上的语句中,还可以添加where条件语句,这些条件是在递归查询的结果集中,再根据 where的条件进行筛选的。
网友评论