AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 166385
Accepted
J. Pichardo
J. Pichardo
Asked: 2017-03-07 13:55:04 +0800 CST2017-03-07 13:55:04 +0800 CST 2017-03-07 13:55:04 +0800 CST

减少列数的设计模式

  • 772

我有一个包含 49 列的表,该表已被规范化。这似乎有点过分,但由于每个字段都是表单的一部分并且主要实体是表单,因此我无法重构以将列委托给另一个表的关系,因此我的问题是“是否有任何模式旨在减少表格中的列数?”

我曾尝试做类似问题 - 答案模式的事情,但由于答案值可以是许多不同的数据类型(枚举、字符串、数字),因此没有通用的方法来解析所有内容。

更新:

我没有考虑过,但数据最终将在 JSON 上序列化以从 WEBApi 提供服务,因此拥有大量嵌套字段可能意味着麻烦。

database-design design-pattern
  • 4 4 个回答
  • 438 Views

4 个回答

  • Voted
  1. a_vlad
    2017-03-07T14:47:29+08:002017-03-07T14:47:29+08:00

    从功能使用方面查看您的表格:

    • 如果您总是通过 ID 访问单个记录,或按顺序处理数据(示例 - 回答所有问题)- 继续使用单个表
    • 如果您计划对一系列记录进行任何分组、过滤或搜索操作 - 主表 PK + 这些操作的列,第二个(和更多) - 其他表。示例 - 选择特定主题的查询。
    • 有 TEXT/BLOB - 移动到第二个表
    • 如果列数不可预测 - 查找 JSON 类型的列

    实际实践表明,3-5 个,最多 10 个参数用于搜索和分组依据。这些列有索引,如果正确创建索引(包括外键)——所有操作都会很快。

    • 1
  2. Best Answer
    RMathis
    2017-03-07T14:48:35+08:002017-03-07T14:48:35+08:00

    从功能的角度看结构有帮助吗?即,您能否重新设计该表以符合应用程序使用它的方式?随着时间的推移,带有一堆最初为空列的稀疏填充表可能会导致性能问题。将这些列隔离到它们自己的表中可能是有意义的。

    填充后如何使用该表?减少行长度(所有列值使用的字节总和)可以减少执行全表扫描所需的时间。如果要扫描表,那么您将需要隔离不需要的列。

    如果任何一种情况都有帮助,包含不需要的列的表将成为另一个表的子表,方法是引用另一个表的主键并在外键上添加唯一约束以确保它保持一对零、一对一的关系。

    • 1
  3. Hannah Vernon
    2017-03-07T14:58:16+08:002017-03-07T14:58:16+08:00

    您是否考虑过问题表和答案表?

    我正在使用 SQL Server;您还没有指定您使用的是什么 DBMS。

    USE tempdb;
    CREATE TABLE dbo.QuestionType
    (
        QuestionTypeID int NOT NULL IDENTITY(1,1)
            CONSTRAINT PK_QuestionType
            PRIMARY KEY CLUSTERED
        , IsString bit NOT NULL
        , IsDate bit NOT NULL
        , IsInteger bit NOT NULL
    );
    
    CREATE TABLE dbo.Questions
    (
        QuestionID int NOT NULL IDENTITY(1,1)
            CONSTRAINT PK_Questions
            PRIMARY KEY CLUSTERED
        , QuestionTypeID int NOT NULL
            CONSTRAINT FK_Questions_QuestionTypeID
            REFERENCES dbo.QuestionType(QuestionTypeID)
        , QuestionText nvarchar(100) NOT NULL
    );
    
    CREATE TABLE dbo.People
    (
        PersonID int NOT NULL IDENTITY(1,1)
            CONSTRAINT PK_People
            PRIMARY KEY CLUSTERED 
        , PersonName nvarchar(100) NOT NULL
    );
    
    CREATE TABLE dbo.Answers
    (
        AnswerID int NOT NULL IDENTITY(1,1)
            CONSTRAINT PK_Answers
            PRIMARY KEY CLUSTERED
        , PersonID int NOT NULL
            CONSTRAINT FK_Answers_PersonID
            FOREIGN KEY REFERENCES dbo.People(PersonID)
        , QuestionID int NOT NULL
            CONSTRAINT FK_Answers_QuestionID
            FOREIGN KEY REFERENCES dbo.Questions(QuestionID)
        , AnswerString nvarchar(1000) NULL
        , AnswerDate datetime NULL
        , AnswerInteger int NULL
    );
    
    INSERT INTO dbo.QuestionType (IsString, IsDate, IsInteger)
    VALUES (1, 0, 0)
        , (0, 1, 0)
        , (0, 0, 1);
    
    INSERT INTO dbo.Questions (QuestionTypeID, QuestionText)
    VALUES (1, 'This is a text question')
        , (2, 'This is a Date question')
        , (3, 'This is an integer question');
    
    INSERT INTO dbo.People (PersonName)
    VALUES ('Max');
    
    INSERT INTO dbo.Answers (PersonID, QuestionID, AnswerString, AnswerDate, AnswerInteger)
    VALUES (1, 1, 'This is a test', NULL, NULL)
        , (1, 2, NULL, '2017-03-06T13:24:00', NULL)
        , (1, 3, NULL, NULL, 27);
    

    您可以在表上放置一个约束dbo.Answers以匹配QuestionTypeID以防止添加无效条目。

    • 1
  4. blobbles
    2017-03-07T19:18:20+08:002017-03-07T19:18:20+08:00

    如果大多数列都是空白的,您应该查看Entity-Attribute-Value方法。这很好地处理了稀疏列并且可以为您节省大量空间。如果你正在设计一个有多个答案和类型的问题,你可以按以下方式设计它:

    Respondent
    --------
    RespondentID         int
    RespondentEmail      varchar(200)
    
    AnswerType
    --------
    AnswerTypeID         int
    AnswerType           varchar(30)
    Size                 int
    
    Question
    --------
    QuestionID           int
    AnswerTypeID         int
    QuestionText         varchar(500)
    
    Answer
    --------
    AnswerID             int
    RespondentID         int
    QuestionID           int
    Value                varchar(500)
    

    受访者表:

    9 / [email protected]
    8 / [email protected]
    

    答案类型表:

    1 / Text / 100
    2 / Int  / NULL
    3 / Date / NULL
    

    问题表:

    4 / 1 / "What is your name?"
    5 / 2 / "How old are you?"
    6 / 3 / "When did you join the company?"
    

    答题表:

    1001 / 9 / 4 / "Jim Smith"
    1002 / 9 / 6 / "2010-05-01"
    1003 / 8 / 4 / "Yohan Sebastian Bach"
    1004 / 8 / 5 / "30"
    1005 / 8 / 6 / "2009-08-05"
    

    一些注意事项:

    • 这样做的好处是不必为可选问题存储空白答案。由于问卷通常遵循可选路径,这意味着您不会存储受访者未遍历的路径的详细信息。

    • 一个简短的说明是,您应该
      在显示
      问题时(以确保您可以呈现正确的项目,例如日期选择器)和提交数据时(以确保您收到正确的
      类型)。


    • 这样做的缺点是总是将答案存储在需要转换为特定类型以执行
      计算的文本字段中。或者,一个优点是可以在
      Answers 表上建立索引,这将使数据检索非常高效。

    • 大多数 DBMS 通常只存储 varchar 类型的使用部分,
      这意味着您尽可能节省空间。

    • Answer 表中的数据可以很容易地在视图中旋转,以获得数据的“正常”视图,每个人每行有一个答案。

    • 1

相关问题

  • 过滤索引是否有助于改进基于输入时间的查询,还是应该避免这种情况?

  • MySQL VARCHAR 和 TEXT 数据类型有什么区别?

  • 存储计算值或根据要求重新计算它们更好吗?[复制]

  • 存储与计算聚合值

  • 在数据仓库中实现多对多关系有哪些方法?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve