关于数据库表设计问题,请教大家

chbq1210 chbq1210 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
现在我想做个图文数据库,故名思义,描述文字比较多。为了使数据库的扩展性好一点,我打算尽量少使用具体数据的属性描述表,因为用户可能随时会增减表的字段,增加字段就增加表的行,显示的时候用行转列。存数据主要用到的表:

IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'tbl_property_codes')
DROP TABLE tbl_property_codes
GO
CREATE TABLE tbl_property_codes --属性代码表
(
id smallint PRIMARY KEY, --索引id
viewid smallint NOT NULL, --视图索引,一个视图就是显示给用户的一个虚拟表,用户可以自定义该表的字段
valtype smallint NOT NULL, --数据类型,int,float, image,text,datatime
name varchar(50) NOT NULL, --属性名称
unit varchar(25) --属性单位
)
IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'tbl_data_int')
DROP TABLE tbl_data_int
GO
CREATE TABLE tbl_data_int --存放int数据
(
id int PRIMARY KEY, --索引id
codeid smallint NOT NULL, --属性代码ID
rowid smallint NOT NULL, --行号
val int NOT NULL --数值
)

IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'tbl_data_float')
DROP TABLE tbl_data_float
GO
CREATE TABLE tbl_data_float --存放float数据
(
id int PRIMARY KEY, --索引id
codeid smallint NOT NULL, --属性代码ID
rowid smallint NOT NULL, --显示行号
val float NOT NULL --数值
)

IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'tbl_data_datetime')
DROP TABLE tbl_data_datetime
GO
CREATE TABLE tbl_data_datetime --存放datetime数据
(
id int PRIMARY KEY, --索引id
codeid smallint NOT NULL, --属性代码ID
rowid smallint NOT NULL, --行号
val datetime NOT NULL --数值
)

IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'tbl_data_image')
DROP TABLE tbl_data_image
GO
CREATE TABLE tbl_data_image --存放float数据
(
id int PRIMARY KEY, --索引id
codeid smallint NOT NULL, --属性代码ID
rowid smallint NOT NULL, --行号
val image NOT NULL --数值
)

IF EXISTS (SELECT * FROM SYSOBJECTS WHERE NAME = 'tbl_data_text')
DROP TABLE tbl_data_text
GO
CREATE TABLE tbl_data_text
(
id int PRIMARY KEY, --索引id
codeid smallint NOT NULL, --属性代码ID
rowid smallint NOT NULL, --行号
val nvarchar(x) NOT NULL --数值
)

三个问题:
1. 这种方式做会不会有重大的缺陷?本人没有多大设计经验。要实现的这个数据库内容不是很多,图片多一些。容量最坏的情况最大几个G吧。
2. 如果可以该方式可行,有两个细节问题,
a. tbl_data_text这里x多长为好?字段值可能两三个汉字,也可以上百个字!有没有必要做成 tbl_data_text_8,tbl_data_text_32,tbl_data_text_256 之类的限制nvarchar的长度,后面根据内容长度存相应表中?
3. 关于上面几个data表,如果是同一组数据,那么rowid相同,显示的时候根据codeid显示属性名,rowid组合数据为具体的行,有没有比较好的查询显示方法?我现在是可以实现,便感觉比较笨。比如有数据:

INSERT INTO tbl_property_codes --建表的时候顺便插的几个记录。
SELECT 1, 0, 3, '中文名称', '' UNION ALL
SELECT 2, 0, 3, '拉丁文名称','' UNION ALL
SELECT 3, 0, 1, '引种号', '' UNION ALL
SELECT 4, 0, 3, '原产地', ''
--插几个样本数据。
INSERT INTO tbl_data_text (id,codeid,rowid,val) VALUES (1,1,1,'小黄鸟鹤蕉')
INSERT INTO tbl_data_text (id,codeid,rowid,val) VALUES (2,2,1,'Heliconia acuminata cv. Yellow Waltz')
INSERT INTO tbl_data_int (id,codeid,rowid,val) VALUES (1,3,1,10000)
INSERT INTO tbl_data_text (id,codeid,rowid,val) VALUES (3,4,1,'巴西或夏威夷')

--查询大概思路,在查询的时候知道当前虚拟表的所有字段id如下面的1,2,3,4,SQL可以让程序生成。但个人觉得虽然可以实现,但是感觉比较笨重。有没有好一点的办法?
SELECT t1.val AS '中文名称',t2.val AS '拉丁文名称',t3.val AS '引种号',t4.val AS '原产地'
FROM
(SELECT id,codeid,rowid,val FROM tbl_data_text WHERE codeid=1) AS t1,
(SELECT id,codeid,rowid,val FROM tbl_data_text WHERE codeid=2) AS t2,
(SELECT id,codeid,rowid,val FROM tbl_data_int WHERE codeid=3) AS t3,
(SELECT id,codeid,rowid,val FROM tbl_data_text WHERE codeid=4) AS t4
WHERE t1.rowid = t2.rowid AND t2.rowid=t3.rowid AND t3.rowid=t4.rowid


请高手指点,不够加分,谢谢!

...全文
评论 7
收藏 已收藏
分享
返回顶部
chbq1210
MS-SQL Server 34,876 成员 254,635 内容