but what happens when an admin by mistake updates the delivery type from UPS mail to Fedex Mail.
Don't let that happen. Privileges are part of database design, illustrated below using PostgreSQL. Principles apply to all client/server SQL dbms.
create table delivery_types (
delivery_type_num integer not null primary key,
delivery_type_name varchar(15) not null unique
);
insert into delivery_types values
(1, 'Email'), (2, 'Download'), (3, 'USPS Mail');
create table orders (
order_num integer primary key,
other_columns char(1) not null default 'x',
delivery_type_num integer not null references delivery_types
on delete no action on update no action
);
revoke insert, update, delete, truncate on delivery_types from public;
grant select on delivery_types to public;
By revoking those privileges from the role "public", only the owner and database superusers can update that table. The foreign key references in "orders" will prevent the owner and database superusers from deleting rows or updating id numbers of rows that are referenced by other tables.
A slightly different approach uses natural keys. This is not denormalization. Both tables "delivery_types" are in 6NF.
create table delivery_types (
delivery_type varchar(15) primary key
);
insert into delivery_types values
('Email'), ('Download'), ('USPS Mail');
create table orders (
order_num integer primary key,
other_columns char(1) not null default 'x',
delivery_type varchar(15) not null references delivery_types
on delete no action on update no action
);
revoke insert, update, delete, truncate on delivery_types from public;
grant select on delivery_types to public;
insert into orders values
(1, 'x', 'Email'), (2, 'x', 'Download'), (3, 'x', 'USPS Mail');
The privileges work just as before--members of the role "public" can select from delivery_types, but they can't change the content. But now even the database superuser can't delete or update rows in delivery_types. The foreign key references prevent it.