edit: Your description of variable attributes that apply only depending on the values in other attributes is a non-relational, non-normalized design. RDBMS may not be the best solution for storing this kind of data. Probably RDF would be a good solution for data that requires this level of flexibility.
My earlier answer, pertaining to RDBMS solutions, is below:
Some people model flexible attributes with the Entity-Attribute-Value design, but this is often too unstructured and you end up fighting with data integrity problems. Use this only if you need a virtually limitless number of entity sub-types.
Other people use Single Table Inheritance, where you put all attribute columns used by all sub-types into one very wide table, and leave them NULL on rows where the attribute is irrelevant to the sub-type. But this has limits because the table can grow too wide, and you lose the ability to make any attributes mandatory, because they must all be nullable.
If you have a relatively small number of entity sub-types, I would recommend creating a dependent table for each group of required attributes. Define the dependent table's primary key as a foreign key to the parent table, so you get a one-to-one relationship.
CREATE TABLE Vehicles (
vehicle_id INT PRIMARY KEY
...attributes common to all vehicles...
);
CREATE TABLE Automobiles (
vehicle_id INT PRIMARY KEY,
...attributes specific to autos...
FOREIGN KEY (vehicle_id) REFERENCES Vehicles(vehicle_id)
);
You can also provide a little more data integrity by encoding the subtype in the primary key of the parent table. That's to make sure a row in Automobiles
cannot reference a motorcycle in Vehicles
.
CREATE TABLE Vehicles (
vehicle_id INT,
vehicle_type VARCHAR(10),
...attributes common to all vehicles...
PRIMARY KEY (vehicle_id, vehicle_type),
FOREIGN KEY (vehicle_type) REFERENCES VehicleTypes (vehicle_type)
);
CREATE TABLE Automobiles (
vehicle_id INT,
vehicle_type VARCHAR(10) CHECK (vehicle_type = 'Automobile'),
...attributes specific to autos...
FOREIGN KEY (vehicle_id, vehicle_type)
REFERENCES Vehicles(vehicle_id, vehicle_type)
);
Of course, you need to create a new dependent table each time you define a new sub-type, but this design does give you a lot more structure to enforce data integrity, NOT NULL attributes, and so on.
The only part you need to enforce in application logic is that to make sure to create a row in Automobiles
for each row in Vehicles
with vehicle_type
= 'Automobile'.