[20181124]关于降序索引问题3.txt

[20181124]关于降序索引问题3.txt

--//链接:blog.itpub.net/267265/viewspace-2221425/,探讨降序索引中索引的键值。
--//实际上使用函数sys_op_descend.

--//链接:http://blog.itpub.net/267265/viewspace-2221527/,探讨了仅仅设计字符串的编码.
--//字符串0x00,0x0000,0x0001,0x00NN(0xNN>=0x02),0x01,0x0100,0x0101,0x01NN(0xNN>=0x02) 单独编码。画一个表格:
ascii码                 编码
---------------------------------------------
0x00                    FEFE
0x0000                  FEFD
0x0001                  FEFC
0x00NN(0xNN>=0x02)      FEFB
0x01                    FEFA
0x0100                  FEF9
0x0101                  FEF8        
0x01NN(0xNN>=0x02)      FEF7
---------------------------------------------

--//对于numbe,date类型如何呢?
--//我在没有测试前,感觉不会出现像字符串那样的编码,因为数据类型,日期类型保存格式规避0x00,这样不会出现像字符串那样的情况.
--//还是通过测试说明问题.

1.环境:
SCOTT@test01p> @ ver1
PORT_STRING                    VERSION        BANNER                                                                               CON_ID
------------------------------ -------------- -------------------------------------------------------------------------------- ----------
IBMPC/WIN_NT64-9.1.0           12.2.0.1.0     Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production              0

2.测试:
SCOTT@test01p> select sys_op_descend(10001),dump(10001,16) c30 from dual ;
SYS_OP_DESCE C30
------------ ------------------------------
3CFDFEF7FDFF Typ=2 Len=4: c3,2,1,2

--//还是有点出乎我的意料,可以发现还是按照上面字符串编码的规律:
3C FD FEF7 FD
c3 02 01  02
--//中间 01 编码 FEF7(按照0x01NN编码).

SCOTT@test01p> select sys_op_descend(1000001),dump(1000001,16) c30 from dual ;
SYS_OP_DESCE C30
------------ ------------------------------
3BFDFEF8FDFF Typ=2 Len=5: c4,2,1,1,2

3B FD FEF8 FD
c4 02 0101 02
--//中间 0101 对应编码 0x0101.

3.继续测试日期看看:
--//注意一个细节date类型,oracle存在2种类型(12,13),保存在数据库块中的类型是type=12.
SCOTT@test01p> select dump(to_date('1980-12-17 00:00:00','yyyy-mm--dd hh24:mi:ss'),16) c40 ,dump(hiredate,16) c40 ,hiredate from emp where rownum=1 ;
C40                                      C40                                      HIREDATE
---------------------------------------- ---------------------------------------- -------------------
Typ=13 Len=8: bc,7,c,11,0,0,0,0          Typ=12 Len=7: 77,b4,c,11,1,1,1           1980-12-17 00:00:00

--//可以发现type=12,时分秒都在原来的基础上+1,这样规避0x00.月份在1-12不会出现0的情况,不加1.日期在1-31,也是一样0的情况.
--//一些细节可以看链接:http://blog.itpub.net/4227/viewspace-68514/

SCOTT@test01p> select sys_op_descend(hiredate) c40 ,dump(hiredate,16) c40,hiredate from emp where rownum=1 ;
C40                                      C40                                      HIREDATE
---------------------------------------- ---------------------------------------- -------------------
884BF3EEFEF8FEFAFF                       Typ=12 Len=7: 77,b4,c,11,1,1,1           1980-12-17 00:00:00


88 4B F3 EE FEF8 FEFA
77 b4 0c 11 0101 01
--//对照前面的编码都可以对上.

4.是否真实是这样呢?建立表测试看看:

SCOTT@test01p> create table t ( id number,cr_date date);
Table created.

insert into t values (1,sysdate);
insert into t values (10001,trunc(sysdate));
insert into t values (1000001,to_date('1980-12-17 00:00:00','yyyy-mm-dd hh24:mi:ss'));
commit ;

SCOTT@test01p> select * from t;
        ID CR_DATE
---------- -------------------
         1 2018-11-24 20:31:32
     10001 2018-11-24 00:00:00
   1000001 1980-12-17 00:00:00

--//分别看看降序索引的情况:
SCOTT@test01p> create  index if_t_all on t(id ,id desc ,cr_date,cr_date desc);
Index created.

SCOTT@test01p> select segment_name,header_file,header_block from dba_segments where owner=user and segment_name in ('IF_T_ALL');
SEGMENT_NAME         HEADER_FILE HEADER_BLOCK
-------------------- ----------- ------------
IF_T_ALL                      11          194

SCOTT@test01p> alter system flush buffer_cache;
System altered.

SCOTT@test01p> alter system dump datafile 11 block 195;
System altered.

--//检查转储文件:
row#0[8003] flag: -------, lock: 0, len=33
col 0; len 2; (2):  c1 02
col 1; len 3; (3):  3e fd ff
col 2; len 7; (7):  78 76 0b 18 15 20 21
col 3; len 8; (8):  87 89 f4 e7 ea df de ff
col 4; len 6; (6):  02 c0 00 be 00 00
row#1[7964] flag: -------, lock: 0, len=39
col 0; len 4; (4):  c3 02 01 02
col 1; len 6; (6):  3c fd fe f7 fd ff
col 2; len 7; (7):  78 76 0b 18 01 01 01
col 3; len 9; (9):  87 89 f4 e7 fe f8 fe fa ff
col 4; len 6; (6):  02 c0 00 be 00 01
row#2[7924] flag: -------, lock: 0, len=40
col 0; len 5; (5):  c4 02 01 01 02
col 1; len 6; (6):  3b fd fe f8 fd ff
col 2; len 7; (7):  77 b4 0c 11 01 01 01
col 3; len 9; (9):  88 4b f3 ee fe f8 fe fa ff
col 4; len 6; (6):  02 c0 00 be 00 02
----- end of leaf block Logical dump -----

--//可以发现与前面单独测试都一样.看来我以前思考问题简单化了.^_^.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/267265/viewspace-2221529/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/267265/viewspace-2221529/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是一个简单的成绩管理系统的C语言代码,满足您的要求: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> // 定义结构体存储学生信息 struct student { char id[20]; char name[20]; char sex[10]; int chinese; int math; int english; int total; float average; }; // 全局变量,存储学生数量 int n = 0; // 函数声明 void add_student(struct student *students); void delete_student(struct student *students); void search_student(struct student *students); void sort_students(struct student *students); void save_students(struct student *students); void load_students(struct student *students); int main() { struct student *students = (struct student*)malloc(sizeof(struct student) * 100); // 假设最多有100名学生,动态分配内存 load_students(students); // 加载已有学生成绩信息 while(1) { printf("欢迎使用学生成绩管理系统!\n"); printf("1. 添加学生信息\n"); printf("2. 删除学生信息\n"); printf("3. 查找学生信息\n"); printf("4. 查看所有学生信息\n"); printf("5. 保存学生信息到文件\n"); printf("6. 退出程序\n"); printf("请选择操作:"); int choice; scanf("%d", &choice); switch(choice) { case 1: add_student(students); break; case 2: delete_student(students); break; case 3: search_student(students); break; case 4: sort_students(students); for(int i = 0; i < n; i++) { printf("学号:%s,姓名:%s,性别:%s,语文:%d,数学:%d,英语:%d,总分:%d,平均分:%.2f\n", students[i].id, students[i].name, students[i].sex, students[i].chinese, students[i].math, students[i].english, students[i].total, students[i].average); } break; case 5: save_students(students); break; case 6: save_students(students); // 退出程序前保存学生成绩信息 printf("谢谢使用!\n"); return 0; default: printf("输入错误,请重新选择!\n"); break; } } free(students); // 释放动态分配的内存 return 0; } // 添加学生信息 void add_student(struct student *students) { printf("请输入学号:"); scanf("%s", students[n].id); printf("请输入姓名:"); scanf("%s", students[n].name); printf("请输入性别:"); scanf("%s", students[n].sex); printf("请输入语文成绩:"); scanf("%d", &students[n].chinese); printf("请输入数学成绩:"); scanf("%d", &students[n].math); printf("请输入英语成绩:"); scanf("%d", &students[n].english); // 计算总分和平均分 students[n].total = students[n].chinese + students[n].math + students[n].english; students[n].average = (float)students[n].total / 3; n++; // 学生数量加1 printf("添加成功!\n"); } // 删除学生信息 void delete_student(struct student *students) { printf("请输入要删除学生的学号:"); char id[20]; scanf("%s", id); // 查找学号对应的学生索引 int index = -1; for(int i = 0; i < n; i++) { if(strcmp(students[i].id, id) == 0) { index = i; break; } } if(index == -1) { printf("未找到该学生信息!\n"); return; } // 将后面的学生信息往前挪一位 for(int i = index; i < n - 1; i++) { students[i] = students[i+1]; } n--; // 学生数量减1 printf("删除成功!\n"); } // 查找学生信息 void search_student(struct student *students) { printf("请输入要查找学生的学号:"); char id[20]; scanf("%s", id); // 查找学号对应的学生信息 int index = -1; for(int i = 0; i < n; i++) { if(strcmp(students[i].id, id) == 0) { index = i; break; } } if(index == -1) { printf("未找到该学生信息!\n"); return; } printf("学号:%s,姓名:%s,性别:%s,语文:%d,数学:%d,英语:%d,总分:%d,平均分:%.2f\n", students[index].id, students[index].name, students[index].sex, students[index].chinese, students[index].math, students[index].english, students[index].total, students[index].average); } // 排序学生信息 void sort_students(struct student *students) { for(int i = 0; i < n-1; i++) { for(int j = i+1; j < n; j++) { if(students[i].total < students[j].total) { struct student tmp = students[i]; students[i] = students[j]; students[j] = tmp; } } } } // 保存学生信息到文件 void save_students(struct student *students) { FILE *fp = fopen("studen_grad.txt", "w"); if(fp == NULL) { printf("文件打开失败!\n"); return; } for(int i = 0; i < n; i++) { fprintf(fp, "%s %s %s %d %d %d\n", students[i].id, students[i].name, students[i].sex, students[i].chinese, students[i].math, students[i].english); } fclose(fp); printf("保存成功!\n"); } // 从文件中加载已有学生成绩信息 void load_students(struct student *students) { FILE *fp = fopen("studen_grad.txt", "r"); if(fp == NULL) { printf("文件打开失败!\n"); return; } while(!feof(fp)) { fscanf(fp, "%s %s %s %d %d %d", students[n].id, students[n].name, students[n].sex, &students[n].chinese, &students[n].math, &students[n].english); students[n].total = students[n].chinese + students[n].math + students[n].english; students[n].average = (float)students[n].total / 3; n++; } fclose(fp); } ``` 希望可以帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值