1

I've built a website in ASP.NET (Umbraco CMS) which has a contest module. The company launches about two contests every month and each contest has an average of ~15.000 contestants. These contestants are stored in a database tables which is designed like this:

Contestant

Id
Name
ZipCity
Address
Country
Email
DateAttended

ZipCity

Id
Zipcode
City

ContestAnswer

Id
AnswerNodeId (Umbraco node id)
ContestNodeId (Umbraco node id)
ContestantId
Date

Each contest can have one question and N number of answer options.

The way I have created it to save the number of records in the database is that for every single answer, I check to see if there's already a contestant with the given e-mail in the Contestant table. If there is, I use that one and if not, I create a new contestant. Also, for every contestant I check if the provided zipcode is already in the ZipCity table and create a reference to that.

Even though I have done it this way instead of blindly creating a new Contestant for every contest, the database keeps getting filled up :-( I've increased the capacity twice now and still getting the same exception after some time:

Could not allocate space for object ... because the filegroup is full.

The company wants to keep the contestants for each contest they launch, so deleting records after a contest has ended is not an option it seems :-/

So, now I've been wondering if there is a smarter way of storing these large amount of data? Thoughts on this?

Any inputs are greatly appreciated!

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
bomortensen
  • 3,346
  • 10
  • 53
  • 74
  • Have you considered using a NoSQL solution like MongoDB or DynamoDB? – Tiago César Oliveira Feb 20 '13 at 13:50
  • 1
    15000x2 a month doesn't sound like a "great amount of data" to me. Why is space so constrained anyway? Wouldn't buying new harddrives be considerably cheaper than paying you to figure out a more economical solution? – spender Feb 20 '13 at 13:50
  • 30000 rows a month doesn't sound like a "great amount of data". Why is storage space a problem? – Kai Feb 20 '13 at 13:52
  • 2
    With such small numbers, your database size constraints must be _really, really_ low. This shouldn't be a problem at all. The only evidence I see that it's a problem is that the database is refusing the submissions, whereas disk space is so cheap and performance getting better that this should be a non-issue and your solution should lie in changing that. – Grant Thomas Feb 20 '13 at 13:52
  • @GrantThomas: yep, like properly properly low. – spender Feb 20 '13 at 13:53
  • 1
    seems [this post](http://stackoverflow.com/questions/1951647/primary-filegroup-is-full-in-sql-server-2008-standard-for-no-apparent-reason) might be able to help you – CuccoChaser Feb 20 '13 at 14:03
  • what kind of back end are you using? SQL Server, MySQL, Oracle...? – DiskJunky Feb 20 '13 at 14:13
  • @DiskJunky As per the tags, and nature of Umbraco by default, clearly SQL Server. – Grant Thomas Feb 20 '13 at 14:20
  • If you are restricting growth, set it to unrestricted. If this is all there is to your database you should have no fear of filling up a disk. – Anthony Queen Feb 20 '13 at 14:21
  • @GrantThomas thanks, didn't see the tag! We have Umbraco instances with with SQL Server and MySQL though... – DiskJunky Feb 20 '13 at 14:32
  • Hi all, and thanks for your input! Appreciated :-) The database is a MSSQL database. I can't just up the capacity freely as the solution is hosted at a dedicated hosting company. Right now, I think the database is at around 150 mb (not sure, have to talk to the administrator about this) which still isn't a lot :) – bomortensen Feb 20 '13 at 14:33

2 Answers2

3

We don't know much about your hard drive setup.

http://blog.sqlauthority.com/2009/05/31/sql-server-create-multiple-filegroup-for-single-database/

http://msdn.microsoft.com/en-us/library/bb522469.aspx

The first link will explain the concept.

The second link will show the syntax.

The 3 items you want to look at are:

[ , SIZE = size [ KB | MB | GB | TB ] ] 
[ , MAXSIZE = { max_size [ KB | MB | GB | TB ] | UNLIMITED } ] 
[ , FILEGROWTH = growth_increment [ KB | MB | GB | TB| % ] ] 

Why?

The first one is the initial size. The second one is the maximum size. And IF THIS IS SET, even though your harddrive may have space on it, the database will cease to grow. The third one is "how big will I expand, if I have not violated the maxsize rule".

Now. You can set the MAXSIZE to UNLIMITED.

HOWEVER. You'll start to get errors when your hard drive fills up.

So you gotta play dba, and pick which option is best.
Personally, I would set the MAXSIZE to something less than the free space on the drive, so you don't hit the edge point.

ALSO: You can create different file groups, and put different different tables on different file groups. This is handy if you know one table will be HUGE, but the other will be small.

So...check to see if you have a MAXSIZE setting set already.

Then you gotta play roulette with your tables and harddrives and filegroups and tables.

You can also put your log files on a different hard drive as another option for space issues.

Here is a good little sample of creating file groups, and then moving tables over to that new file group.

http://www.daveturpin.com/2010/09/move-tables-to-new-filegroup/

Below is a script that I have for creating a database using SQLCMD Mode. Note the directories must "pre exist" (on the server, not your local machine if you are aren't actually sitting on the sql server).

: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
granadaCoder
  • 26,328
  • 10
  • 113
  • 146
  • Hi granadaCoder, thanks for your answer! :) I have read the articles and come to the conclusion that: maybe the amount of data isn't really huge! It might aswell be the hosting provider which solutions are small-to-medium sized. I can't just go and change any of the capacity settings since the server is administrated by the hosting company only :-) I'll talk it through with the administrators and see if we can come up with a solution. – bomortensen Feb 20 '13 at 14:40
  • Ok. Yeah, I didn't know you had a hosting company. Then they will have to check the settings. – granadaCoder Feb 20 '13 at 14:45
  • You may have to "purge the log file" every once in a while. You have to see if they consider that a part of your space limitations. But I think with the info above, you'll have the correct "jargon" to talk to them. Reminder. If you don't mark this as an answer, people will keep trying to answer it. – granadaCoder Feb 20 '13 at 14:46
  • yes, sorry I didn't inform you about the hosting company and the restrictions involved. You're right about purging the log file. I've only considered the internal logging table in Umbraco which needs to be cleared now and then, but never thought of the DB log file! Will have to talk to them about that one. I'll mark your answer as accepted :-) Should help a lot of other people with the same problem! Thanks again! – bomortensen Feb 20 '13 at 14:50
  • My guess is that the log file is where you're gonna find an issue. You data may not be big (it doesn't seem that way)... but the log can fill up quicker than you think. Good luck. – granadaCoder Feb 20 '13 at 15:03
0

There is not much you can do in terms of reducing space that will cause the data requirements to go down. Also, 15k per month is not much really unless you are on some shared sql hosting that has severe limitations. Anyway, not much you can do here unfortunately.

Perhaps you can try with enabling sql server compression. Check these articles for more details

http://www.bradmcgehee.com/2010/03/an-introduction-to-data-compression-in-sql-server-2008/

http://msdn.microsoft.com/en-us/library/cc280449.aspx

David Smithers
  • 2,354
  • 1
  • 21
  • 13