I'm adapting an audit scheme from this: https://weblogs.asp.net/jongalloway/adding-simple-trigger-based-auditing-to-your-sql-server-database which calls for creating an audit table like this:
CREATE TABLE Audit
(
AuditID [int]IDENTITY(1,1) NOT NULL,
Type char(1),
TableName varchar(128),
PrimaryKeyField varchar(1000),
PrimaryKeyValue varchar(1000),
FieldName varchar(128),
OldValue varchar(1000),
NewValue varchar(1000),
UpdateDate datetime DEFAULT (GetDate()),
UserNamevarchar(128)
)
I want to ensure that I'm storing as little as possible for each row that is inserted into the Audit table. In my case, I can shorten the width of TableName, PrimaryKeyField, PrimaryKeyValue and FieldName because I know the actual max lengths of those things. I have one particular table that has a particular column defined as nvarchar(2000), so if I stay with this generic approach I'll need to use nvarchar(2000) for OldValue and NewValue.
I was wondering about SQL Server's internal optimizations regarding storage space actually used in a page. When a row is stored with long varchars or nvarchars, is the full defined length actually used to store the row in a page, or does SQL Server only store the actual bytes used. For example, if only Hello! is stored in OldValue above, how many bytes will the OldValue actually occupy in the page for such a row?