Product Identification Standards
Comprehensive guide to product identification systems including NDC codes, UPC barcodes, GTIN standards, and serialization for healthcare, retail, and supply chain applications.
What is Product Identification?
Product identification systems assign unique codes to products for tracking, inventory management, and regulatory compliance. Different industries use different standards—healthcare uses NDC codes for drugs, retail uses UPC barcodes for consumer goods, and global supply chains use GTIN for standardization.
Modern product identification includes serialization (unique identifiers for individual items), 2D barcodes (DataMatrix, QR codes), and RFID tags for real-time tracking. Understanding these systems is critical for database design, inventory management, and regulatory compliance.
NDC: National Drug Code (Healthcare)
NDC Format
NDC codes are 10-digit identifiers in three segments:
- Labeler Code (4-5 digits): Manufacturer/distributor
- Product Code (3-4 digits): Specific drug formulation
- Package Code (1-2 digits): Package size/type
Common NDC Formats:
- 4-4-2:
0069-2587-10(Pfizer Lipitor 10mg) - 5-3-2:
00002-142-02(Eli Lilly Humalog) - 5-4-1:
00173-0687-4(GlaxoSmithKline)
Database Schema
CREATE TABLE product_ndc ( prod_id VARCHAR(50) PRIMARY KEY, ndc_cd VARCHAR(11) NOT NULL, -- National Drug Code ndc_labeler_cd VARCHAR(5), -- Manufacturer code ndc_prod_cd VARCHAR(4), -- Product code ndc_pkg_cd VARCHAR(2), -- Package code prod_nm VARCHAR(200) NOT NULL, -- Product name generic_nm VARCHAR(200), -- Generic name strength_txt VARCHAR(50), -- e.g., "10mg" dosage_form_cd VARCHAR(20), -- Tablet, capsule, etc. route_admin_cd VARCHAR(20), -- Oral, IV, etc. mfr_nm VARCHAR(200), -- Manufacturer name dea_schedule_cd VARCHAR(2), -- DEA schedule (C2-C5) active_flag CHAR(1) DEFAULT 'Y', -- Y/N eff_dt DATE NOT NULL, -- Effective date term_dt DATE, -- Termination date created_dttm TIMESTAMP DEFAULT NOW(), updated_dttm TIMESTAMP DEFAULT NOW() ); CREATE INDEX idx_ndc_cd ON product_ndc(ndc_cd); CREATE INDEX idx_prod_nm ON product_ndc(prod_nm); CREATE INDEX idx_mfr_nm ON product_ndc(mfr_nm);
UPC & GTIN: Retail Product Codes
GTIN Family
- GTIN-8: 8-digit code for small packages
- GTIN-12 (UPC-A): 12-digit standard US/Canada barcode
- GTIN-13 (EAN-13): 13-digit international barcode
- GTIN-14: 14-digit code for case/pallet shipping
UPC-A Structure (12 digits)
Example: 012345678905
- 0: Number system (0-1 = UPC, 3 = Drugs/Health)
- 12345: Manufacturer code (assigned by GS1)
- 67890: Product code (assigned by manufacturer)
- 5: Check digit (calculated)
Database Schema
CREATE TABLE product_upc ( prod_id VARCHAR(50) PRIMARY KEY, gtin_cd VARCHAR(14) NOT NULL, -- GTIN code (zero-padded) upc_cd VARCHAR(12), -- UPC-A barcode ean_cd VARCHAR(13), -- EAN-13 barcode gtin_type_cd VARCHAR(10), -- GTIN-8/12/13/14 prod_nm VARCHAR(200) NOT NULL, -- Product name brand_nm VARCHAR(100), -- Brand name category_cd VARCHAR(50), -- Product category unit_size_qty DECIMAL(10,2), -- Size amount unit_measure_cd VARCHAR(10), -- oz, lb, ml, etc. retail_price_amt DECIMAL(10,2), -- Suggested retail price mfr_cd VARCHAR(20), -- Manufacturer GS1 code mfr_nm VARCHAR(200), -- Manufacturer name active_flag CHAR(1) DEFAULT 'Y', eff_dt DATE NOT NULL, term_dt DATE, created_dttm TIMESTAMP DEFAULT NOW() ); CREATE UNIQUE INDEX idx_gtin_cd ON product_upc(gtin_cd); CREATE INDEX idx_upc_cd ON product_upc(upc_cd); CREATE INDEX idx_prod_nm ON product_upc(prod_nm);
Product Serialization (Track & Trace)
Serialization assigns a unique serial number to each individual product unit for track-and-trace compliance (required for pharmaceuticals under DSCSA).
GS1 Serialized GTIN (SGTIN)
Format: GTIN + Serial Number
(01)00614141123452(21)ABC123456789
- (01): GTIN Application Identifier
- 00614141123452: 14-digit GTIN
- (21): Serial Number Application Identifier
- ABC123456789: Unique serial number
Database Schema
CREATE TABLE product_serialization ( serial_id VARCHAR(50) PRIMARY KEY, gtin_cd VARCHAR(14) NOT NULL, -- Product GTIN serial_nbr VARCHAR(50) NOT NULL, -- Unique serial number lot_nbr VARCHAR(50), -- Lot/batch number exp_dt DATE, -- Expiration date mfg_dt DATE, -- Manufacturing date status_cd VARCHAR(20), -- Active, Sold, Recalled, etc. location_cd VARCHAR(50), -- Current location last_scan_dttm TIMESTAMP, -- Last scan timestamp created_dttm TIMESTAMP DEFAULT NOW(), updated_dttm TIMESTAMP DEFAULT NOW(), UNIQUE(gtin_cd, serial_nbr) ); CREATE INDEX idx_serial_nbr ON product_serialization(serial_nbr); CREATE INDEX idx_gtin_cd ON product_serialization(gtin_cd); CREATE INDEX idx_status ON product_serialization(status_cd);
Common SQL Queries
Find Product by NDC Code
SELECT prod_id, ndc_cd, prod_nm, generic_nm, strength_txt, mfr_nm FROM product_ndc WHERE ndc_cd = '0069-2587-10' AND active_flag = 'Y' AND CURRENT_DATE BETWEEN eff_dt AND COALESCE(term_dt, '9999-12-31');
Validate UPC Check Digit
-- UPC check digit calculation (Modulo 10 algorithm)
WITH upc_data AS (
SELECT
upc_cd,
prod_nm,
-- Sum odd positions (multiply by 3)
(CAST(SUBSTRING(upc_cd, 1, 1) AS INT) * 3 +
CAST(SUBSTRING(upc_cd, 3, 1) AS INT) * 3 +
CAST(SUBSTRING(upc_cd, 5, 1) AS INT) * 3 +
CAST(SUBSTRING(upc_cd, 7, 1) AS INT) * 3 +
CAST(SUBSTRING(upc_cd, 9, 1) AS INT) * 3 +
CAST(SUBSTRING(upc_cd, 11, 1) AS INT) * 3) AS odd_sum,
-- Sum even positions
(CAST(SUBSTRING(upc_cd, 2, 1) AS INT) +
CAST(SUBSTRING(upc_cd, 4, 1) AS INT) +
CAST(SUBSTRING(upc_cd, 6, 1) AS INT) +
CAST(SUBSTRING(upc_cd, 8, 1) AS INT) +
CAST(SUBSTRING(upc_cd, 10, 1) AS INT)) AS even_sum,
CAST(SUBSTRING(upc_cd, 12, 1) AS INT) AS check_digit
FROM product_upc
)
SELECT
upc_cd,
prod_nm,
check_digit,
(10 - ((odd_sum + even_sum) % 10)) % 10 AS calculated_check,
CASE
WHEN check_digit = (10 - ((odd_sum + even_sum) % 10)) % 10
THEN 'Valid'
ELSE 'Invalid'
END AS validation_result
FROM upc_data;Track Product Movement (Serialization)
SELECT
ps.serial_nbr,
p.prod_nm,
ps.lot_nbr,
ps.exp_dt,
ps.status_cd,
ps.location_cd,
ps.last_scan_dttm,
CASE
WHEN ps.exp_dt < CURRENT_DATE THEN 'Expired'
WHEN ps.exp_dt < CURRENT_DATE + INTERVAL '30 days' THEN 'Expiring Soon'
ELSE 'Valid'
END AS expiry_status
FROM product_serialization ps
JOIN product_upc p ON ps.gtin_cd = p.gtin_cd
WHERE ps.status_cd = 'Active'
AND ps.gtin_cd = '00614141123452'
ORDER BY ps.last_scan_dttm DESC;Integration & Best Practices
Data Validation Rules
- ✓NDC Normalization: Always store as 11-character format with hyphens (5-4-2)
- ✓GTIN Zero-Padding: Pad UPC-12 to GTIN-14 by adding "00" prefix
- ✓Check Digit Validation: Always validate UPC/GTIN check digits on data entry
- ✓Expiration Tracking: Monitor exp_dt and flag expiring products 30-60 days in advance
- ✓Audit Trail: Log all status changes, location updates, and scans for compliance
Performance Optimization
- →Index on gtin_cd, ndc_cd, and serial_nbr for fast lookups
- →Partition serialization tables by mfg_dt or status_cd for large volumes
- →Archive inactive products older than 7 years to history tables
- →Use materialized views for product catalogs refreshed nightly
Common Abbreviations in Product Identification
Product Codes:
- ndc_cd - National Drug Code
- gtin_cd - Global Trade Item Number Code
- upc_cd - Universal Product Code
- serial_nbr - Serial Number
- lot_nbr - Lot Number
Related Resources
Need Help with Product Identification?
Explore our complete glossary of healthcare and retail data standards