【问题标题】:Best design for two different tables with 90% same columns具有 90% 相同列的两个不同表的最佳设计
【发布时间】:2020-03-19 07:36:07
【问题描述】:

我有一个 feature_values 表,其中包含用户存储的数据:他们可以编辑和更新此表。

user_feature_values
user  | year  |  quarter | gdp | other 
---------------------------------------
1       2018      Q1        1.5    1.2
1       2018      Q2        1.6    1.5
5       2017      Q1       -1.2    1.0
.......................................
.............
4       2017      Q4        1.0    2.5

还有另一个类似的表存储默认值。用户无法编辑此内容。

default_feature_values
country  | year  |  quarter  | gdp  | other 
---------------------------------------
5          2018      Q1        1.8    2.0
10         2015      Q2        1.4    1.2
120        2017      Q3       -1.2    1.0
.......................................
.............
115        2016      Q4        1.5    2.15

当前情况: 创建用户后,我会根据用户所在的国家/地区将默认值复制到user_feature_values。这样他们就可以使用自己的值编辑表中的默认值。稍后,他们可以选择默认值;从default_feature_values 表复制到user_feature_values 表。

这是一个糟糕的设计吗?

这可以实现多少?

【问题讨论】:

  • # 作为第一个字符的命名表似乎是一个糟糕的选择(尽管我无法真正解释为什么我有这种偏见)。也就是说,我无法弄清楚问题在问什么。它是否要求对设计提出意见?或者它是在寻求一种实现功能的方法。第一个建议出于一个原因关闭;第二个换另一个。
  • @GordonLinoff 不,我没有这样命名它们。我只是使用# 来区分表和实际的 feature_values 来解释场景。我正在征求对设计的意见,以及是否可以以更好的方式实施。
  • 。 .而“基于意见”是关闭问题的第五个关闭原因(根据您的观点,我假设您知道)。你可以用不同的方式表达一个类似的问题——例如,基于性能。我想说这种设计有一个差距——用户可能想“记住”他们的价值观并回到他们身边,但你的设计不支持这一点。
  • 要添加到@GordonLinoff 的评论中,这是“基于意见的”,我非常同意这一点,,,乍一看数据的样子以及你所说的我很可能会去一个表feature_values(带有默认列值)和一个feature_values_permission 表,用户可以编辑,哪些不可以编辑feature_values id。
  • 一个用户可以在多个国家吗?那么,user... 表不需要country 列吗?

标签: mysql sql database design-patterns database-design


【解决方案1】:

您可以将此解决方案用于 SQL 服务器,但我想这种方式稍加改动就适用于 mysql(我对 mysql 没有任何想法):

step1:创建类似这个查询的链接服务器(或在对象资源管理器中设置其他方式):

USE [master]
GO

EXEC master.dbo.sp_addlinkedserver @server = N'SetMainDBaddressHERE', @srvproduct=N'SQL Server'
 /* For security reasons the linked server remote logins password is changed with ######## */
EXEC master.dbo.sp_addlinkedsrvlogin     @rmtsrvname=N'SetMainDBaddressHERE',@useself=N'False',@locallogin=NULL,@rmtuser=N'DBuserName(like sa)',@rmtpassword='########'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'collation compatible', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'data access', @optvalue=N'true'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'dist', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'pub', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'rpc', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'rpc out', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'sub', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'connect timeout', @optvalue=N'0'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'collation name', @optvalue=null
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'lazy schema validation', @optvalue=N'false'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'query timeout', @optvalue=N'0'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'use remote collation', @optvalue=N'true'
GO

EXEC master.dbo.sp_serveroption @server=N'SetMainDBaddressHERE', @optname=N'remote proc transaction promotion', @optvalue=N'true'
GO

第二步:使用 information_schema.columns 进行比较和更改命令,如下所示:

with t as(
    select TABLE_NAME,column_name,s.DATA_TYPE,s.CHARACTER_MAXIMUM_LENGTH,
            case    when TABLE_NAME like 'vw_%' then N'Alter view as other DB'
                    when CHARACTER_MAXIMUM_LENGTH is null and s.DATA_TYPE in ('image','datetime') then 'Alter table '+TABLE_NAME+' add '+column_name+' '+s.DATA_TYPE
                    when CHARACTER_MAXIMUM_LENGTH is null then 'Alter table '+TABLE_NAME+' add '+column_name+' '+s.DATA_TYPE +' null' 
            else  'Alter table '+TABLE_NAME+' add '+column_name+' '+s.DATA_TYPE +'('+convert(nvarchar,CHARACTER_MAXIMUM_LENGTH)+')'
            end as Command
    from [MainServerDBadress].DBname.INFORMATION_SCHEMA.COLUMNS s where TABLE_NAME like 'vw_%' or  TABLE_NAME like 'tbl_%'
    )
Select TABLE_NAME,column_name,DATA_TYPE,CHARACTER_MAXIMUM_LENGTH , Command
from t 
where  TABLE_NAME+column_name not in ( select TABLE_NAME+column_name from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME like 'vw_%' or  TABLE_NAME like 'tbl_%')
order by 1,2

我对表使用alter 命令。 我对所有视图使用“vw_”,对所有表使用“tbl_tablename”。如果您没有此模型,则可以删除上述查询的一些代码。

希望有人将这个 SQL 数据库解决方案升级到 mysql。

【讨论】:

  • 本网站上的 SQL 标记不适用于 SQL Server SQL 方言,它适用于有效的 ANSI/ISO 结构化查询语言 (SQL) 规范语言代码,也因为标记了 MySQL 标记,答案应该有MySQL 有效语法...此提供的代码不会在 MySQL 上运行..
猜你喜欢
  • 2019-01-11
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多