Oracle APEX (21.2) 数据库设计 – 拆分数字 vs 规范化

huangapple go评论53阅读模式
英文:

Oracle APEX (21.2) Database Design - Split Numbers vs Normalization

问题

I know this is overall a database design question, but I think there is validity of listing it with APEX due to the nature of the implementation I am thinking of with use of APEX_STRING.SPLIT_NUMBERS api.

With that out of the way, I have a consent form table that once created will need to be assigned to different 'target' groups (e.g. School Pyramid, School Level [High School, Middle School, Elementary], Grade Level [1-12], or even specific schools [by a School ID]). More than 1 pyramid can be targeted (total of 5), more than 1 school can be targeted (up tp 10) for a given consent form.

My initial thought was a table that has all these target groups (with associated reference/lookup tables REF_PYRAMID, REF_SCHOOL_LEVEL, REF_SCHOOL). Then store the IDs in the associated column as a list of numbers (eg. 2:12:13). Then I would use APEX_STRING.SPLIT_NUMBERS & MEMBER OF when I need to run SQL check to see if parent is part of an authorized target & should have access to the consent form.

I am not used to storing info this way so wondering if there are any downsides of this approach? This keeps the record flat and allows the option to make a consent form school-wide, which is just Y/N option not multiple targets, like the others.

dpc_consent_form_target {
  target_id                 number         [primary key]
  consent_form_id           number         [ref: > dpc_consent_form.consent_form_id]
  school_wide               char(1)        [chk 'Y','N']
  pyramid_id                number
  school_id                 number
  school_level_id           number
  grade_id                  number
}

My second thought was to normalize the design, like I usually would, so that each, say School, would have it's own record in a TARGET table, but then I'm not sure how best to handle the single "record" of school-wide.

table dpc_consent_form_target {
  target_id                 number         [primary key]
  consent_form_id           number         [ref: > dpc_consent_form.consent_form_id]
  target_type_id            number         [ref: > dpc_ref_target_type.target_type_id]
  target_value_id           number
  created_by                varchar2(50)
  created_date              timestamp
  updated_by                varchar2(50)
  updated_date              timestamp
}

table dpc_ref_target_type {
  target_type_id            number         [primary key]
  target_type_name          varchar2(50)
  active_flag               char(1)
  created_by                varchar2(50)
  created_date              timestamp
  updated_by                varchar2(50)
  updated_date              timestamp
  deleted_by                varchar2(50)
  deleted_date              timestamp
}

TARGET TYPE VALUES:
1 - pyramid_id
2 - school_level_id
3 - school_id
4 - grade_id
5 - school_wide

Thanks in advance for any advice.

英文:

I know this is overall a database design question, but I think there is validity of listing it with APEX due to the nature of the implementation I am thinking of with use of APEX_STRING.SPLIT_NUMBERS api.

With that out of the way, I have a consent form table that once created will need to be assigned to different 'target' groups (e.g. School Pyramid, School Level [High School, Middle School, Elementary], Grade Level [1-12], or even specific schools [by a School ID]). More than 1 pyramid can be targeted (total of 5), more than 1 school can be targeted (up tp 10) for a given consent form.

My initial thought was a table that has all these target groups (with associated reference/lookup tables REF_PYRAMID, REF_SCHOOL_LEVEL, REF_SCHOOL). Then store the IDs in the associated column as a list of numbers (eg. 2:12:13). Then I would use APEX_STRING.SPLIT_NUMBERS & MEMBER OF when I need to run SQL check to see if parent is part of an authorized target & should have access to the consent form.

I am not used to storing info this way so wondering if there are any downsides of this approach? This keeps the record flat and allows the option to make a consent form school-wide, which is just Y/N option not multiple targets, like the others.

dpc_consent_form_target {
  target_id                 number         [primary key]
  consent_form_id           number         [ref: > dpc_consent_form.consent_form_id]
  school_wide               char(1)        [chk 'Y','N']
  pyramid_id                number
  school_id                 number
  school_level_id           number
  grade_id                  number
}

My second thought was to normalize the design, like I usually would, so that each, say School, would have it's own record in a TARGET table, but then I'm not sure how best to handle the single "record" of school-wide.

table dpc_consent_form_target {
  target_id                 number         [primary key]
  consent_form_id           number         [ref: > dpc_consent_form.consent_form_id]
  target_type_id            number         [ref: > dpc_ref_target_type.target_type_id]
  target_value_id           number
  created_by                varchar2(50)
  created_date              timestamp
  updated_by                varchar2(50)
  updated_date              timestamp
}

table dpc_ref_target_type {
  target_type_id            number         [primary key]
  target_type_name          varchar2(50)
  active_flag               char(1)
  created_by                varchar2(50)
  created_date              timestamp
  updated_by                varchar2(50)
  updated_date              timestamp
  deleted_by                varchar2(50)
  deleted_date              timestamp
}

TARGET TYPE VALUES:
1 - pyramid_id
2 - school_level_id
3 - school_id
4 - grade_id
5 - school_wide

Thanks in advance for any advice.

答案1

得分: 3

请注意,代码部分不需要翻译,以下是翻译好的内容:

然后将这些ID存储在相关列中,作为一组数字(例如2:12:13)。

不要这样做。

Apex会连接RETURN值,例如Shuttle项目,一切都在Apex世界中正常工作。但是,一旦您离开Apex并必须编写基于这种数据的查询,您将不得不将值拆分为行,以便将它们连接到其他表格。

这是可行的,可以完成,没有问题;但是,这不是正确的方法,因为数据模型没有规范化。此外,您无法在其上创建任何有意义的索引,因为您将对冒号分隔的字符串进行索引,而不是每个值;当您具有小数据集时,性能没有差异,但在大数据集上性能将受到影响。

该怎么办?创建一个表格,通过外键约束引用其主表格。

英文:

> Then store the IDs in the associated column as a list of numbers (eg. 2:12:13).

Don't do that.

Apex concatenates RETURN values for e.g. Shuttle items and everything works just fine in Apex world. However, as soon as you step out of it and have to write queries based on such a data, you'll have to split values into rows so that you could join them to other table(s).

It works, can be done, no problem; however, that's not the way to do it because data model isn't normalized. Also, you can't create any meaningful index on it because you'd be indexing a colon-separated string, not each value within; no difference in performance when you have a small data set, but it will suffer on large data sets.

What to do? Create a child table which will reference its master table via foreign key constraint.

huangapple
  • 本文由 发表于 2023年4月13日 20:29:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76005455.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定