具有类别(可选子类别)和子子类别(服务)的数据库
database with Category, (Optional subcategory) and sub-subcategory (service)
以为我一个人就能搞定,但是...我觉得我浪费了太多时间...
大家好!我正在为 Room 数据库结构而苦苦挣扎——我不确定我的方法是否正确。我想要实现的是能够将服务(子子类别)添加到类别中,但也可能有可选的子类别:
类别 -> 服务
类别 -> 可选子类别 -> 服务
我已经做了什么(跳过了一些基本的代码部分):
a) 创建实体
@Entity
class Category
int id
String name
@Entity
class Subcategory
int id
String name
int categoryID
@Entity
class Subcategory
int id
String name
int categoryID
int subcategoryID
b) 创建连接 table
@Entity
class Join
int id
int categoryID
int subcategoryID
int serviceID
当一个类别有包含任何服务的子类别时,这很简单:
id | categoryId | SubcategoryId| ServiceId|
-------------------------------------------
1 | 1 | 1 | 1 |
1 | 1 | 1 | 2 |
但如果没有子类别且服务仅属于类别:
id | categoryId | SubcategoryId| ServiceId|
-------------------------------------------
1 | 1 | null | 1 |
我将 null
作为 SubcategoryId 并检查子类别是否为 null
所以问题是:这种方法在关系数据库设计方面是否正确?
或者我应该:
1. 创建类别-子类别、子类别-服务、类别-服务连接 tables 并最终以某种方式将它们连接到一个大连接中?
2. 或者在服务中添加 categoryId 和 subcategoryId ?
非常感谢任何评论、提示和技巧! :)
而不是加入到其他关系tables,我会使用以下方法:
假设您只有两个类别,一个是主要 (主要类别),第二个是次要类别 (子类别)。
我会像这样在单个 table 中为 Category
创建实体:
@Entity
class Category
int id // It's our primary key here
String name
int parentId // To detect if category is Main/Sub. How? "Null" if Main, "main category" id if child
现在关于 Service
个实体:
@Entity
class Service
int id
String name
//This is our foreign key from Category table
int categoryId //It can be Main/Sub category id from "Category" Table, how to detect it's Main/Sub? Check it from category table using "parentId".
Why this approach?
Because,
1 Service relies upon Category, so it doesn't matter for Service
whether Category is Main/Sub. All it knows is that it's Category for
itself.
2 Now for Category, Why no separate tables for both of them?
because, even though, it is Sub-category, we need to treat them like
Category(and it really is), So better treat it like Category and
differentiate both by one new parameter named parentId
for it.
有一种旧设计叫做 Nested Set。这种设计的优点是相对简单,你可以创建任意深度的类别和子类别。查询速度很快,可以通过多种方式检索数据:例如,显示某个类别的第 4 级子类别。
一个缺点是查询有些复杂,但一旦您克服了学习曲线就会非常直观。
另一个缺点是 DML 非常昂贵,因此这仅在数据一旦建立非常稳定的情况下才有用。
如果这符合您的需要,我会在 this answer 中提供更多详细信息以及大量示例代码。
以为我一个人就能搞定,但是...我觉得我浪费了太多时间... 大家好!我正在为 Room 数据库结构而苦苦挣扎——我不确定我的方法是否正确。我想要实现的是能够将服务(子子类别)添加到类别中,但也可能有可选的子类别:
类别 -> 服务
类别 -> 可选子类别 -> 服务
我已经做了什么(跳过了一些基本的代码部分):
a) 创建实体
@Entity
class Category
int id
String name
@Entity
class Subcategory
int id
String name
int categoryID
@Entity
class Subcategory
int id
String name
int categoryID
int subcategoryID
b) 创建连接 table
@Entity
class Join
int id
int categoryID
int subcategoryID
int serviceID
当一个类别有包含任何服务的子类别时,这很简单:
id | categoryId | SubcategoryId| ServiceId|
-------------------------------------------
1 | 1 | 1 | 1 |
1 | 1 | 1 | 2 |
但如果没有子类别且服务仅属于类别:
id | categoryId | SubcategoryId| ServiceId|
-------------------------------------------
1 | 1 | null | 1 |
我将 null
作为 SubcategoryId 并检查子类别是否为 null
所以问题是:这种方法在关系数据库设计方面是否正确?
或者我应该: 1. 创建类别-子类别、子类别-服务、类别-服务连接 tables 并最终以某种方式将它们连接到一个大连接中? 2. 或者在服务中添加 categoryId 和 subcategoryId ?
非常感谢任何评论、提示和技巧! :)
而不是加入到其他关系tables,我会使用以下方法:
假设您只有两个类别,一个是主要 (主要类别),第二个是次要类别 (子类别)。
我会像这样在单个 table 中为 Category
创建实体:
@Entity
class Category
int id // It's our primary key here
String name
int parentId // To detect if category is Main/Sub. How? "Null" if Main, "main category" id if child
现在关于 Service
个实体:
@Entity
class Service
int id
String name
//This is our foreign key from Category table
int categoryId //It can be Main/Sub category id from "Category" Table, how to detect it's Main/Sub? Check it from category table using "parentId".
Why this approach?
Because,
1 Service relies upon Category, so it doesn't matter for Service whether Category is Main/Sub. All it knows is that it's Category for itself.
2 Now for Category, Why no separate tables for both of them? because, even though, it is Sub-category, we need to treat them like Category(and it really is), So better treat it like Category and differentiate both by one new parameter named
parentId
for it.
有一种旧设计叫做 Nested Set。这种设计的优点是相对简单,你可以创建任意深度的类别和子类别。查询速度很快,可以通过多种方式检索数据:例如,显示某个类别的第 4 级子类别。
一个缺点是查询有些复杂,但一旦您克服了学习曲线就会非常直观。
另一个缺点是 DML 非常昂贵,因此这仅在数据一旦建立非常稳定的情况下才有用。
如果这符合您的需要,我会在 this answer 中提供更多详细信息以及大量示例代码。