I'm setting up an asset tracking database. Assets vary among black berries, PCs, servers, monitors, speakers, keyboards, mice, chairs, desks, cubicals, cubical walls, printers, refrigerators, microwaves... the whole range of things. That range would be my Category table:
create table AssetManagement.zCategory(
zCategoryId int identity primary key,
CategoryDescription varchar(15) unique not null
)
Computers would easily have a category, manufacturer and model, but some assets (chairs or others) may only have a model. Some may only have a manufacturer.
I believe it would be a good design to use a good database design to enforce the following:
- If a Model's Manufacturer is known,
- it's not possible to store the same model ID elsewhere in the database with a different category or manufacturer
- An Asset stored in the database must have a category
- Using an id for a description of 'unknown' in any of the 3 would be uncomfortable, but may be necessary)
So while a model might have a known manufacturer, an asset might have a model, or a manufacturer, or both, it should always have a category.
Here's what I've come up with so far, and I thought about using a trigger to enforce what direct foreign keys would not
create table AssetManagement.zModel(
zModelId int identity primary key,
zModelDescription varchar(15) unique not null,
zAssetCategoryId int not null references AssetManagement.zAssetCategory(zAssetCategoryId)
)
create table AssetManagement.zManufacturer(
zManufacturerId int identity primary key,
zManufacturerDescription varchar(15) unique not null
)
create table AssetManagement.zProduct
(
zProductId int identity primary key,
zProductDescription varchar(35),
zAssetCategoryId int references AssetManagement.zAssetCategory(zAssetCategoryId),
zModelId int references AssetManagement.zModel(zModelId),
zManufacturerId int references AssetManagement.zManufacturerId(zManufacturerId)
)
create table Assetmanagement.Asset(
AssetId int identity primary key,
Tag varchar(15),
zProductId int not null references assetmanagement.zProduct,
zLocationId int references assetmanagement.zLocation(zLocationId),
EmployeeId int references assetmanagement.employee(employeeId),
PurchasedDate datetime,
PurchasedBy int references assetmanagement.employee(employeeId),
DisposalDate datetime,
Depreciated float,
AddedBy int references assetmanagement.employee(employeeId),
AddedDate datetime
)
Or have a missed the boat and there's a way to design this that's convienent (having modelid, manufacturerid, and product type all on the assets table directly while enforcing proper uniqueness?
I would be doing it this way.
Basically, an Asset is something with a tag on it. It contains no information about category, manufacturer or model. You're denomrmalizing your data if you do it that way. It contains a foreign key to Model, which is that information. I'd see model and manufacturer as being nothing more than freeform text but your requirements may turn either or both into tables in certain circumstances.
You could store who has the asset in the Asset table but you get no history that way (although that can be done with an Asset History or audit table).