1

I realise there have been debates about this, although I can find a real definitive answer.

A lot of times, this question leads to a definition of what varchar(MAX) etc is, their actual limits, and what NOT to use.

What I want to find out is this:
I am giving the user an option to type/paste in whatever they want to in a text box, without limit.
This could be anything from a word, to a byte array dump of an image.

I need to then be able to quickly reference to this data at a later stage, using its TITLE or ID.

What would be the best way to go about storing this data into a DB? I have read that using varchar(MAX) stops indexing, and generally should not be used.

I'm not really well-off in SQL, so I imagine a possible solution would be to split this string into arrays of 4000, and store them like that.

Is this a good lead? Or am I missing something obvious?

General Model:

    public string a_Title { get; set; }

    public string a_Content { get; set; }

    public string a_AdditionalInfo { get; set; }

Where a_Content will be stored as the unknown.

4

4 回答 4

2

I believe you don't have to worry about your storage type right now. You really have choice between varchar(n), varchar(max), nvarchar(n), nvarchar(max), even varbinary and text/ntext. All of them have its virtues and drawbacks. You can even chuck your blob-like strings into a file using FILESTREAM.

However, I believe you want to reference your data via some int or short varchar field, and you want to get your results relatively quick (not blazing-hot-get-me-data-yesterday-fast). There can be more or less optimal ways to do it, but don't think about that now.

I suggest this:

  • create a table structure that satisfies your needs
  • fill it with some dummy data
  • implement data access using your favorite data access layer

When you feel happy enough, create a performance test wit, say, few thousands of accesses. This is the first time you want to optimize performance. Until then I would even forget the indexing itself.

P.S. - don't split it to 4000-bytes chunks; this is a very awkward workaround and it can cause random search misses (not exactly random, you could find the bug after slow and painful debugging session)

于 2013-08-07T13:42:56.213 回答
1

VarChar(MAX)适用于像您这样的情况。

即使您将数据分块为NVarChar(4000)(或VarChar(8000))字节段以允许构建索引,这些索引到底有什么价值?

您还将为弄清楚段的开始和结束位置而头疼,然后在令人讨厌的 SQL 语句或一些中间层客户端代码中重构它们。

此外,VarChar(MAX)NVarChar(MAX)在可能的情况下保持在行内。这意味着直到您分别使用40018001字符。

于 2013-08-07T13:29:32.470 回答
0

I'd be tempted to use varbinary(max) for this "catch-all" data column you're describing. The varbinary data type can store text (see below), byte arrays and entire files. The size limit is 2GB, but the nice things about varbinary (as opposed to deprecated image) is that you can return/download a portion of the data using a simple substring function. So, if you only wanted the first 100mb of some data, you'd used:

Declare @data as varbinary(100000000)
select @data = substring(DataColumn,0,100000000) from SomeDataTable where ID = 1

To insert text into varbinary you'd use:

declare @test table (
   data varbinary(max) not null,
   datatype varchar(10) not null
)

--insert varchar
insert into @test (data, datatype) 
values cast('Your Text Here' as varbinary(max)), 'varchar'

-- insert nvarchar
insert into @test (data, datatype) select cast(N'YourTextHere' as varbinary(max)), 'nvarchar'

-- see the results
select data, datatype from @test
select cast(data as varchar(max)) as data_to_varchar, datatype from @test
select cast(data as nvarchar(max)) as data_to_nvarchar, datatype from @test
于 2013-08-07T13:43:41.577 回答
0

一种方法是构建两个表,并利用VARCHAR(MAX)

CREATE TABLE table1 (ID INT PRIMARY KEY IDENTITY(1, 1), Name VARCHAR(1024) NOT NULL);
CREATE TABLE table1Text (ID INT PRIMARY KEY, data VARCHAR(MAX) NOT NULL);

IDin是对table1Text的外键引用table1。这种方法的好处是您仍然可以索引table1 并且可以提供全文搜索,table1Text而不会遇到每个表相互影响的任何问题。

于 2013-08-07T13:29:31.473 回答