SQL Server · tblEvent · SCADA Practice

SQL Data Types and Keys Explained

Learn SQL Server data types and database keys from first principles, then apply them to the real SQF_DB.dbo.tblEvent automation table.

DATETIME2 migration Equipment foreign key Fan status tradeoff Candidate keys

Learning Overview

Part 1: Data-type basicsPart 2: Key fundamentalsPart 3: tblEvent practiceEstimated time: 150 minutes

Prerequisites / What You’ll Need

  • Basic understanding of tables, rows and columns
  • SQL Server or SQL Server Express test instance
  • SQL Server Management Studio
  • A disposable copy of SQF_DB.dbo.tblEvent for exercises
Beginner-friendly approach

First understand what each SQL type and key does. Then use tblEvent only as a practical example for selecting types, enforcing relationships and identifying rows.

  • Data types encode process rules, not only storage size.
  • Foreign keys reject equipment identifiers that do not exist.
  • A binary bit is correct only for a permanently two-state domain.
  • A candidate key is a business guarantee, not a guess based on sample data.

Learn SQL Data Types and Keys from Basics

This guide covers SQL data types basics, primary and foreign keys, candidate and alternate keys, SQL Server constraints and practical tblEvent examples.

1. What Is a SQL Data Type?

A SQL data type defines the kind of value a column, variable or parameter can hold. It determines valid range, storage representation, precision, supported operations, comparison behavior and conversion rules.

For automation data, select a type from the engineering meaning:

  • What is the minimum and maximum possible value?
  • Is the number exact or an approximate measurement?
  • How many decimal places are meaningful?
  • Can the value be unknown or unavailable?
  • Does text require multiple languages?
  • Is the timestamp UTC, local time or offset-aware?
  • How many rows will be stored and how will they be queried?
Type names can mislead across systems: a PLC INT is commonly 16-bit, while SQL Server int is 32-bit. Compare ranges, not names alone.

2. Major SQL Server Data-Type Families

FamilyCommon typesAutomation examples
Exact integertinyint, smallint, int, bigintModes, counters, sequence numbers, equipment IDs
Exact decimaldecimal(p,s), numeric(p,s)Setpoints, totals and values requiring fixed decimal rounding
Approximate numericreal, floatMeasurements where IEEE floating-point approximation is acceptable
BooleanbitOn/off, enabled/disabled, acknowledged flag
Date and timedate, time, datetime2, datetimeoffsetEvents, shifts, batches and source/receive timestamps
Non-Unicode textchar, varcharControlled ASCII codes and identifiers
Unicode textnchar, nvarcharAlarm messages, operator comments and multilingual labels
Binarybinary, varbinaryHashes, documented payloads or files
Specialuniqueidentifier, rowversion, xmlDistributed event IDs, concurrency markers and structured documents

3. Integer Types and Ranges

SQL typeRangeTypical automation use
tinyint0 to 255Unsigned byte, small state code or priority
smallint-32,768 to 32,767PLC signed 16-bit INT
int-2,147,483,648 to 2,147,483,647PLC DINT, IDs and medium counters
bigintSigned 64-bit rangeIdentity keys, high counters, durations and sequence numbers

Choose the smallest type that safely covers the approved lifetime range, not merely today's sample values. For an identity key in a high-frequency event table, estimate row growth before choosing int or bigint.

4. Exact and Approximate Numeric Types

decimal and numeric

decimal(p,s) and numeric(p,s) are synonyms. Precision p is total digits; scale s is digits to the right of the decimal point. SQL Server supports precision up to 38.

TemperatureSetpoint decimal(8,3), -- five integral + three fractional digits
ProductionTotal     decimal(18,3)

real and float

These are approximate binary floating-point types. They are suitable for many sensor values, but decimal fractions may not compare exactly. Do not use floating-point equality as a business rule.

RequirementPreferred direction
Fixed decimal precision and repeatable roundingdecimal(p,s)
Scientific/engineering approximate values and wide rangereal or float
Binary statebit
Currency-like fixed decimalExplicit decimal(p,s) chosen with finance/DBA review

5. Character, Unicode and Length

  • char(n): fixed-length non-Unicode text.
  • varchar(n): variable-length non-Unicode text.
  • nchar(n): fixed-length Unicode text.
  • nvarchar(n): variable-length Unicode text.

Use nvarchar for multilingual HMI messages and operator comments. Define a realistic maximum length; do not choose max by default. Length is part of the interface contract and must match application parameter definitions.

ChargeNo     varchar(50)  NOT NULL,
AlarmText   nvarchar(500) NOT NULL,
OperatorNote nvarchar(1000) NULL

6. Date and Time Types for Automation

TypeStoresTypical use
dateDate onlyProduction date or scheduled day
time(n)Time of dayRecipe or shift time without a date
datetime2(n)Date/time with selectable fractional precisionUTC process and event timestamp
datetimeoffset(n)Date/time plus UTC offsetWhen the original offset is part of the fact
datetimeLegacy date/time with .000/.003/.007 roundingBackward compatibility
SQL timestamp is not time: SQL Server timestamp is a deprecated synonym for rowversion. Use datetime2 or datetimeoffset for actual time.

For SCADA events, a clear design is EventTimeUtc datetime2(3) plus a separate receive timestamp and source sequence when event ordering matters.

7. NULL and Column Constraints

NULL means missing, unknown or not applicable. It is not equal to zero, false or an empty string. Query it using IS NULL and IS NOT NULL.

Data types define representation; constraints define additional rules:

ConstraintPurposetblEvent example
NOT NULLValue is mandatoryDT datetime2(3) NOT NULL
DEFAULTSupplies a value when omittedIsActive bit DEFAULT (1)
CHECKRestricts valid domain/rangeTemperature range or status-code list
UNIQUEPrevents duplicate key values(ChargeNo, DT) after business approval
PRIMARY KEYChosen row identityID
FOREIGN KEYEnforces parent relationshipSQF_No to Equipment

8. What Is a Database Key?

A key is one column or a combination of columns used to identify rows or relate tables. Key theory separates possible identities from the one selected for implementation.

Key termMeaningExample
Super keyAny column set that uniquely identifies a row, including unnecessary columns(ID, DT) when ID alone is unique
Candidate keyMinimal super key; no column can be removed and retain uniquenessID, or approved (ChargeNo, DT)
Primary keyCandidate key selected as the main row identitytblEvent.ID
Alternate keyCandidate key not selected as primaryApproved unique (ChargeNo, DT)
Composite keyKey containing two or more columns(ChargeNo, DT)
Natural keyIdentity derived from business dataCharge/timestamp when guaranteed by process
Surrogate keyArtificial identity without business meaningIdentity column ID
Foreign keyChild column(s) referencing a parent candidate/primary keySQF_No references EquipmentID

9. Primary, Candidate and Alternate Keys

A primary key must be unique and NOT NULL. SQL Server creates a unique index to enforce it. A table has one primary-key constraint, although that key can contain multiple columns.

Candidate keys are a logical design concept. To enforce alternate keys in SQL Server, use UNIQUE constraints after confirming minimality, mandatory columns and the real business rule. Existing sample uniqueness alone does not prove a candidate key.

CONSTRAINT PK_tblEvent PRIMARY KEY (ID),
CONSTRAINT UQ_tblEvent_Charge_DT UNIQUE (ChargeNo, DT)

10. Foreign Keys and Referential Integrity

A foreign key prevents a child row from referencing a parent that does not exist. It does not automatically create an index on the child column, and it does not decide what should happen on delete/update; those behaviors must be designed explicitly.

EquipmentParent master table
EquipmentIDPrimary key
SQF_NoForeign key
tblEventChild event rows
IntegrityReject unknown furnace

For production history, avoid cascade delete unless the retention and audit policy explicitly permits deleting dependent events.

11. Use tblEvent as the Running Example

The reference table demonstrates how data types, constraints and keys work together:

ColumnConceptDesign question
IDSurrogate primary keyWill int or bigint cover lifetime row volume?
DTDate/time typeWhat precision and UTC convention are required?
SQF_NoForeign keyDoes every event reference valid equipment?
ChargeNoNatural identity componentIs it mandatory and stable?
Fan_StatusDomain/type tradeoffBinary forever, or future multi-state?
USE [SQF_DB];
GO

SELECT
    c.name AS ColumnName,
    t.name AS DataType,
    c.max_length,
    c.precision,
    c.scale,
    c.is_nullable
FROM sys.columns AS c
JOIN sys.types AS t ON t.user_type_id = c.user_type_id
WHERE c.object_id = OBJECT_ID(N'dbo.tblEvent')
ORDER BY c.column_id;

12. Practice 1: Change DT from DATETIME to DATETIME2(3)

USE [SQF_DB];
GO

ALTER TABLE [dbo].[tblEvent]
ALTER COLUMN [DT] DATETIME2(3) NOT NULL;
GO
Reasondatetimedatetime2(3)
Fractional secondsRounded to .000, .003 or .007 incrementsTrue millisecond precision
Date range1753 through 99990001 through 9999
Storage8 bytes7 bytes
New developmentLegacy compatibilityModern recommended type

Existing datetime values can be represented by datetime2(3). The operational risk is the table alteration itself: a large history table can be locked and generate substantial log activity. Benchmark the migration on a restored copy and schedule an approved maintenance window.

Expected result: sys.columns reports DT as datetime2 with scale 3 and is_nullable = 0.

13. Practice 2: Add an Equipment Foreign Key

Create a small equipment master table, then relate tblEvent.SQF_No to its primary key.

CREATE TABLE [dbo].[Equipment]
(
    EquipmentID   int IDENTITY(1,1) PRIMARY KEY,
    EquipmentName varchar(100) NOT NULL,
    IsActive      bit NOT NULL
        CONSTRAINT DF_Equipment_IsActive DEFAULT (1)
);
GO

INSERT INTO dbo.Equipment (EquipmentName)
VALUES ('SQF-1'), ('SQF-2'), ('SQF-3');
GO

Before adding the foreign key, find orphaned values already present:

SELECT DISTINCT e.SQF_No
FROM dbo.tblEvent AS e
LEFT JOIN dbo.Equipment AS q
    ON q.EquipmentID = e.SQF_No
WHERE e.SQF_No IS NOT NULL
  AND q.EquipmentID IS NULL;

The result must be empty, or the orphan rows must be corrected through an approved data-cleaning rule.

ALTER TABLE [dbo].[tblEvent]
ADD CONSTRAINT FK_tblEvent_Equipment
    FOREIGN KEY (SQF_No)
    REFERENCES dbo.Equipment(EquipmentID);
GO

Prove the constraint without retaining test data

BEGIN TRANSACTION;

BEGIN TRY
    INSERT INTO dbo.tblEvent (DT, SQF_No, ChargeNo, Fan_Status)
    VALUES ('2026-08-04T12:00:00.000', 999, 'CHG-3001', 'ON');
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() AS ErrorNumber,
           ERROR_MESSAGE() AS ErrorMessage;
END CATCH;

ROLLBACK TRANSACTION;

SQL Server should return error 547 because equipment 999 does not exist. Repeat in a rolled-back transaction with SQF_No = 1; it should pass the foreign-key check if all other required columns and constraints are satisfied.

14. Practice 3: Decide Between VARCHAR(10) and BIT for Fan_Status

Decision factorvarchar(10)bit
StorageUp to ten bytes plus row overheadSeveral bit columns can share one byte
Raw readabilityON/OFF is self-explanatoryReader must know 1=ON and 0=OFF
IntegrityNeeds check/reference rule to prevent typosOnly 0, 1 or NULL
Future statesCan support FAULT/MAINTENANCERestricted to binary

First inventory the real data:

SELECT Fan_Status, COUNT(*) AS RowCount
FROM dbo.tblEvent
GROUP BY Fan_Status
ORDER BY Fan_Status;

If the approved domain is strictly ON/OFF, migrate through a new column:

ALTER TABLE dbo.tblEvent
ADD FanStatusBit bit NULL;
GO

UPDATE dbo.tblEvent
SET FanStatusBit = CASE
    WHEN UPPER(LTRIM(RTRIM(Fan_Status))) = 'ON'  THEN 1
    WHEN UPPER(LTRIM(RTRIM(Fan_Status))) = 'OFF' THEN 0
    ELSE NULL
END;
GO

-- Stop if any non-NULL source value failed conversion
IF EXISTS
(
    SELECT 1
    FROM dbo.tblEvent
    WHERE Fan_Status IS NOT NULL
      AND FanStatusBit IS NULL
)
    THROW 50001, 'Unexpected Fan_Status value; migration stopped.', 1;
GO

ALTER TABLE dbo.tblEvent DROP COLUMN Fan_Status;
EXEC sys.sp_rename
    'dbo.tblEvent.FanStatusBit',
    'Fan_Status',
    'COLUMN';
GO
Confirm the process first: if FAULT, MAINTENANCE, LOCAL or UNKNOWN is a real state, keep a status code with a check constraint or reference table instead of forcing those meanings into one bit.

15. Practice 4: Primary, Candidate and Alternate Keys

The reference identifies ID as the chosen surrogate primary key and proposes two natural combinations:

  • (ChargeNo, DT): one event per charge per timestamp.
  • (SQF_No, DT): one event per furnace per timestamp.

First prove that the current data is unique:

SELECT ChargeNo, DT, COUNT(*) AS DuplicateCount
FROM dbo.tblEvent
GROUP BY ChargeNo, DT
HAVING COUNT(*) > 1;

SELECT SQF_No, DT, COUNT(*) AS DuplicateCount
FROM dbo.tblEvent
GROUP BY SQF_No, DT
HAVING COUNT(*) > 1;

An empty result proves only that today's data has no duplicates. The process owner must confirm the future business rule. With millisecond timestamps, two legitimate events can still share the same instant.

ALTER TABLE dbo.tblEvent
ADD CONSTRAINT UQ_tblEvent_Charge_DT
    UNIQUE (ChargeNo, DT);
GO

-- Optional only when the plant rule is confirmed
ALTER TABLE dbo.tblEvent
ADD CONSTRAINT UQ_tblEvent_SQFNo_DT
    UNIQUE (SQF_No, DT);
GO
Key columns should be mandatory: if (ChargeNo, DT) is a true candidate key, define both columns as NOT NULL after cleaning existing NULLs. Otherwise it is not a complete business identity.

16. Review the Remaining tblEvent Data Types

ColumnsCurrent patternReview question
TMvarchar(10)Is it redundant once DT contains date and time?
Event_From, Event_Tovarchar(100)Should these reference a controlled process-stage table?
Temp_Set, Temp_ActfloatIs approximate binary floating point acceptable, or is fixed decimal required?
Cp_Set, Cp_ActfloatWhat precision/scale matches instrument and report resolution?
Oil_Set/Act, Jacket_Set/ActfloatWhat are validated engineering ranges and NULL meanings?
ChargeNovarchar(50)Is it non-Unicode by contract, unique per plant, and mandatory?

Do not change these columns merely for uniformity. Capture actual values, client parameter types, report calculations and process rules before selecting new types.

17. Use a Safe Migration Sequence

  1. Back up and prove restore on a non-production copy.
  2. Record row count, table size, constraints, indexes and dependent objects.
  3. Profile NULLs, duplicates, orphan equipment and status values.
  4. Create/reference master data before the foreign key.
  5. Run alterations in a tested maintenance window.
  6. Validate row counts, constraints, query results and application writes.
  7. Retain a reviewed rollback or restore decision point.

Large table alterations can be fully logged and blocking. Measure duration and log growth using a production-sized restored copy.

18. Verify the Final Data Types and Keys

SELECT
    c.name AS ColumnName,
    t.name AS DataType,
    c.max_length,
    c.precision,
    c.scale,
    c.is_nullable
FROM sys.columns AS c
JOIN sys.types AS t ON t.user_type_id = c.user_type_id
WHERE c.object_id = OBJECT_ID(N'dbo.tblEvent')
  AND c.name IN (N'ID', N'DT', N'SQF_No', N'ChargeNo', N'Fan_Status');

SELECT
    kc.name AS KeyName,
    kc.type_desc
FROM sys.key_constraints AS kc
WHERE kc.parent_object_id = OBJECT_ID(N'dbo.tblEvent');

SELECT fk.name AS ForeignKeyName
FROM sys.foreign_keys AS fk
WHERE fk.parent_object_id = OBJECT_ID(N'dbo.tblEvent');
Expected result: DT is datetime2(3); Fan_Status matches the approved domain; the equipment FK exists; and only confirmed unique constraints are present.

19. Migration Troubleshooting

ProblemCauseCorrection
ALTER COLUMN blocksLarge table or long concurrent transactionsTest duration, stop conflicting workload and use an approved window
Foreign key creation failsOrphan SQF_No valuesRun the orphan query and correct/map rows before adding the FK
BIT migration produces NULLUnexpected text or spaces/case variantsProfile all values; do not drop the source until every row is resolved
UNIQUE constraint failsDuplicate ChargeNo/DT or SQF_No/DTInvestigate business meaning; do not delete duplicates blindly
Valid events are rejected laterNatural key rule was too strict for millisecond eventsRevise business identity, perhaps using source event ID or sequence
Application insert failsClient still sends old text/type or invalid equipmentUpdate parameters and deploy database/application changes together

Complete Practice Checklist: tblEvent

Reference lab
Before you start
  • Use a disposable restored database.
  • Capture starting schema and row counts.
  • Do not run the migration against a live WinCC history database.
1

Modernize DT

Change DT to datetime2(3) NOT NULL and verify scale.

Millisecond precision and row count are preserved.
2

Enforce equipment identity

Create Equipment, clean orphans, add the FK and run rolled-back good/bad inserts.

999 is rejected and a valid EquipmentID passes the FK check.
3

Migrate Fan_Status

Profile states, confirm binary behavior and migrate through a new bit column.

No unreviewed text value is silently converted to NULL.
4

Prove candidate keys

Run duplicate queries and obtain process-owner approval before adding uniqueness.

Only genuine business keys are enforced.

Reference Exercise Summary

ExerciseConcept reinforced
1Choosing date/time precision and a modern SQL type
2Foreign keys and referential integrity
3Storage, readability, integrity and extensibility tradeoffs
4Primary, candidate and alternate keys

Frequently Asked Questions

Why change DT to datetime2(3)?

It provides true millisecond precision, a wider range and seven-byte storage while avoiding legacy datetime rounding increments.

Can I add the foreign key when data already exists?

Only after every non-NULL SQF_No matches Equipment. Find and resolve orphaned rows first.

Should Fan_Status be bit or varchar?

Use bit only for a permanently binary ON/OFF state. Use a constrained status code/reference table if more states are valid.

Is ChargeNo plus DT always a candidate key?

No. The plant must guarantee one event per charge at the timestamp precision and both columns should be mandatory.

Can ALTER COLUMN lock the table?

Yes. Test on production-sized data and schedule backup, log capacity, downtime and rollback appropriately.

Get the SQL Reporting and Automation syllabus

Share your details and a Softwell advisor will contact you with practical training options.

Practice SQL with real SCADA tables

Join practical online, classroom or corporate SQL and automation training.

Request Course Details
Verified learning pathway

Discuss SQL Fundamentals and Automation Training

Explore practical SQL Server, PLC/SCADA integration and industrial data training options.

Content reviewed: 4 August 2026

☎ Call WhatsApp ✉ Email Enquire Now