Java 将筛选器集传递到数据库类以供SQL使用的最佳设计

Java 将筛选器集传递到数据库类以供SQL使用的最佳设计,java,database-design,derby,Java,Database Design,Derby,我正在开发一个抽认卡应用程序。部分原因是用户可以选择过滤难度级别和类别的结果,将来可能会有更多选项。有关用户屏幕的快速模型,请参见此图 闪存卡的数据存储在单个表中的Derby DB中。一列表示级别。每个类别的一列,用Y或N表示卡是否属于该类别 目前,我有一个过滤器类,每个复选框只有一个变量。然后我将其传递给数据库类。但从这里开始,需要一组复杂的if/else语句来构建正确的SELECT语句查询 1有没有更好的设计方法? 2我的1表方法是注定要失败还是在这种情况下可以?我正走进什么陷阱 来源:古

我正在开发一个抽认卡应用程序。部分原因是用户可以选择过滤难度级别和类别的结果,将来可能会有更多选项。有关用户屏幕的快速模型,请参见此图

闪存卡的数据存储在单个表中的Derby DB中。一列表示级别。每个类别的一列,用Y或N表示卡是否属于该类别

目前,我有一个过滤器类,每个复选框只有一个变量。然后我将其传递给数据库类。但从这里开始,需要一组复杂的if/else语句来构建正确的SELECT语句查询

1有没有更好的设计方法? 2我的1表方法是注定要失败还是在这种情况下可以?我正走进什么陷阱


来源:

古老的格言是,在计算机科学中有三个数字——零、一或无限。我建议不要为每个级别创建一个布尔列,而是为级别创建一个枚举或整数列,或者使用一个类别表和两个类别之间的连接,使用外键将问题链接到一个或多个类别,或者使用枚举或整数的类别列。这样,在添加/删除/重命名新类别或级别时,就不会修改数据库架构。它独立于它包含的数据

此外,这将大大简化SQL查询。比较:

SELECT * FROM questions WHERE category1 = false AND category2 = false AND category3 = false ... and (level = 1 OR level = 2);


在过去类似的情况下,我创建了一个整数列,可以对其执行逐位操作。解释如下:

首先为每个值分配一个二进制数字-

cat1  cat2  cat3 cat4
----  ----  ---- ----
1     2     4    8
接下来,您将向主表中添加一个整数列,我们称之为选项。当数字转换为二进制时,每个数字将表示设置了1、2、3或4类天气。例如:

二进制中的5=0101=cat1已设置,cat2未设置,cat3已设置,cat4未设置

id | name         | options
---------------------------
1  | name1        | 5
2  | name2        | 2
3  | name3        | 7
4  | name4        | 6
我们现在可以对options列使用位操作来确定允许哪些选项。示例:

要在不关心其他类别的情况下获取设置了类别2的所有记录,请执行以下操作:

2&选项=2

这将返回记录2、3和4

要获取设置了cat2和cat3的所有记录,我们将执行以下逐位操作:

6&选项=6

这将返回记录3和4

要获取设置了类别1和类别3的所有记录,我们将执行以下逐位操作:

5&选项=5

这将返回记录1和3

仅3类设置:

4 |选项=4

第3类未设置:

4&options=0


这可能是一个很难理解的概念,所以如果您有任何问题,请告诉我。在我看来,一旦你掌握了这个概念,这可能是完成你想要做的事情的最简单的方法。

我只有一列是整数级别。使用枚举或整数是一个有趣的想法。我当然不想处理一个永无止境的不断增长的专栏那么,列是否会包含以逗号分隔的枚举值列表?这是否可以处理一个问题行可能具有多个类别列的数字(例如包含1,3)的情况?或者,这需要我为每个类别创建一个表,然后用键链接它们吗?从问题中选择*,类别在1,3中;返回category=1或category=3的任何行。单列仅允许每个问题包含一个类别。如果您想允许一个问题属于多个类别,则需要一个联接表3表格总计-问题、类别和问题类别。那么,你会在问题1中有记录,这是一家什么样的银行?和两类记录1,厌女症;2,白痴,然后是联接表中的两条记录,将问题1链接到类别1,将问题1链接到类别2。这是一个可靠的想法。我们一直在嵌入式编程中做这种事情。很明显,根据long或int的不同,会有32或64个类别的限制,但无论如何,为了GUI的缘故,也必须有一个限制,这样才能使它停留在一个表的解决方案中。更重要的情况是当用户需要Cat 1或Cat 3时。在这种情况下,您只需使用选项按位AND并检查>1,对吗?所有这些都可以在SQL语句中完成吗?或者我必须返回所有记录,然后逐级检查并应用位掩码吗?我只是检查了一下,不幸的是Derby不支持按位操作。我只在支持按位操作的SQL Server中使用过此方法,因此您必须查看此方法是否适合您的情况。您需要检查以下内容以查看是否设置了cat 1或cat 3:5&options>0
cat1  cat2  cat3 cat4
----  ----  ---- ----
1     2     4    8
id | name         | options
---------------------------
1  | name1        | 5
2  | name2        | 2
3  | name3        | 7
4  | name4        | 6