我在ASP.NET(Umbraco CMS)中建立了一个有竞赛模块的网站。该公司每月举办两场比赛,每场比赛平均有约15.000名参赛者。这些参赛者存储在数据库表格中,其设计如下:
参赛者
Id
Name
ZipCity
Address
Country
Email
DateAttended
ZipCity
Id
Zipcode
City
ContestAnswer
Id
AnswerNodeId (Umbraco node id)
ContestNodeId (Umbraco node id)
ContestantId
Date
每个比赛可以有一个问题和N
个答案选项。
我创建它以保存数据库中的记录数量的方式是,对于每个答案,我检查是否已经有Contestant
表中给定电子邮件的参赛者。如果有,我使用那个,如果没有,我创建一个新的选手。此外,对于每个参赛者,我都会检查所提供的邮政编码是否已经在ZipCity
表格中,并创建对此的参考。
即使我这样做了,而不是盲目地为每个比赛创建一个新的Contestant
,数据库仍然被填满:-(我现在增加了两倍的容量,但仍然得到相同的例外一段时间:
无法为对象分配空间...因为文件组已满。
该公司希望为他们发起的每场比赛保留参赛者,因此在比赛结束后删除记录似乎不是一种选择: - /
所以,现在我一直想知道是否有更智能的方法来存储这些大量数据?对此的想法?
非常感谢任何投入!
答案 0 :(得分:3)
我们对您的硬盘设置了解不多。
http://blog.sqlauthority.com/2009/05/31/sql-server-create-multiple-filegroup-for-single-database/
http://msdn.microsoft.com/en-us/library/bb522469.aspx
第一个链接将解释这个概念。
第二个链接将显示语法。
您要查看的3个项目是:
[ , SIZE = size [ KB | MB | GB | TB ] ]
[ , MAXSIZE = { max_size [ KB | MB | GB | TB ] | UNLIMITED } ]
[ , FILEGROWTH = growth_increment [ KB | MB | GB | TB| % ] ]
为什么?
第一个是初始尺寸。 第二个是最大尺寸。如果这是设置的,即使您的硬盘可能有空间,数据库也将停止增长。 第三个是“如果我没有违反maxsize规则,我会扩大多大。”
现在。您可以将MAXSIZE设置为UNLIMITED。
但是。当您的硬盘驱动器填满时,您将开始出错。
所以你必须玩dba,并选择哪个选项最好 就个人而言,我会将MAXSIZE设置为小于驱动器上的可用空间,因此您不会达到边缘点。
ALSO: 您可以创建不同的文件组,并将不同的表放在不同的文件组中。 如果你知道一个表会很大,但另一个表很小,这很方便。
所以......检查你是否已经设置了MAXSIZE设置。
然后你必须用你的桌子和硬盘以及文件组和表格来玩轮盘赌。
您还可以将日志文件放在另一个硬盘驱动器上作为空间问题的另一个选项。
这是一个很好的小样本,用于创建文件组,然后将表移动到该新文件组。
http://www.daveturpin.com/2010/09/move-tables-to-new-filegroup/
下面是我使用SQLCMD模式创建数据库的脚本。 请注意,目录必须“预先存在”(如果您实际上并不是在SQL服务器上,则在服务器上,而不是本地计算机上)。
:Setvar DBName MyFirstDatabase01
:Setvar DataFilesBaseDirectory "C:\WUTemp\Some Folder\"
:Setvar LogFilesBaseDirectory "C:\WUTemp\Some Folder\"
:Setvar DatabasePrimaryDataFileStartSizeMB 9
:Setvar DatabasePrimaryDataFileGrowthMB 8
:Setvar DatabasePrimaryLogFileStartSizeMB 7
:Setvar DatabasePrimaryLogFileGrowthMB 6
Use [master];
GO
if exists (select * from sysdatabases where name='$(DBName)')
BEGIN
DROP DATABASE [$(DBName)];
END
GO
--Create Database $(DBName)
--G--O
DECLARE @device_directory_data NVARCHAR(520)
DECLARE @device_directory_log NVARCHAR(520)
--SELECT @device_directory_data = SUBSTRING(filename, 1, CHARINDEX(N'master.mdf', LOWER(filename)) - 1) FROM master.dbo.sysaltfiles WHERE dbid = 1 AND fileid = 1
--SELECT @device_directory_log = SUBSTRING(filename, 1, CHARINDEX(N'master.mdf', LOWER(filename)) - 1) FROM master.dbo.sysaltfiles WHERE dbid = 1 AND fileid = 1
select @device_directory_data = '$(DataFilesBaseDirectory)'
select @device_directory_log = '$(LogFilesBaseDirectory)'
print @device_directory_data
print @device_directory_log
EXECUTE (N'CREATE DATABASE $(DBName)
ON PRIMARY (NAME = N''$(DBName)'', FILENAME = N''' + @device_directory_data + N'$(DBName).mdf'', SIZE = $(DatabasePrimaryDataFileStartSizeMB) MB, FILEGROWTH = $(DatabasePrimaryDataFileGrowthMB)MB)
LOG ON (NAME = N''$(DBName)_log'', FILENAME = N''' + @device_directory_log + N'$(DBName).ldf'', SIZE = $(DatabasePrimaryLogFileStartSizeMB) MB, FILEGROWTH = $(DatabasePrimaryLogFileGrowthMB)MB)')
DECLARE @logsize char(1)
SELECT @logsize = CASE WHEN convert(varchar, Serverproperty('ProductVersion')) LIKE '9%'
--THEN '10'
--ELSE '5'
THEN '13'
ELSE '14'
END
EXECUTE(N'ALTER DATABASE $(DBName)
ADD LOG FILE (NAME = N''$(DBName)_log2'',
FILENAME = N''' + @device_directory_log + N'$(DBName)log2.ldf'', SIZE = ' + @logsize + ' MB)')
-- Make the database case sensitive to clean up the development effort
-- EXECUTE(N'ALTER DATABASE $(DBName) COLLATE SQL_Latin1_General_CP1_CS_AS')
exec sp_dboption '$(DBName)','trunc. log on chkpt.','true'
exec sp_dboption '$(DBName)','select into/bulkcopy','true'
GO
GO
答案 1 :(得分:0)
在减少会导致数据要求下降的空间方面,您无能为力。 此外,每月15k并不是真的,除非你在一些有严重限制的共享sql托管。 无论如何,不幸的是,你在这里做的并不多。
也许您可以尝试启用sql server压缩。查看这些文章了解更多详情
http://www.bradmcgehee.com/2010/03/an-introduction-to-data-compression-in-sql-server-2008/