From Wikipedia..."Database design is the process of producing a detailed data model of a database. This data model contains all the needed logical and physical design choices and physical storage parameters needed to generate a design in a data definition language, which can then be used to create a database."
From Ross...A good first step designing a database is deciding what it will be used for. Is it intended primarily to store transactions (OLTP) and needs to be optimized to write, read, update or delete transaction records or primarily for analysis, reporting or forcasting (OLAP) requiring quick retrieval and analysis of data. Generally the more transactional a database intended to be the more normalization is required.
Break any data fields that could be considered to consist of multiple parts into separate fields. A good example is the breaking of a persons name into its constituent first, middle and last name. The disassembling data like this makes life easier later on when standardizing data entry.
Standardize data fields. Make sure that any fields that contain a limited set of values express the value in a starndard form For instance if you have a column which is to contain a value for grade do not allow it to contain multiple values to indicate the same thing...don't allow "1st" and "First" to indicate grade one. Pick one and stick with it.
Remove repeating groups. Repeating groups can often be identified as data that contains separators ei. "Bird/Eagle", "Bird/Sparrow" "Mammal/Rabbit", "Insect/Beetle". Repeating groups data can be difficult to include in reporting or manipulate as the queries would be complicated and likely have less then stellar performance. An easy way to deal with repeating data is to assign an ID to the unique values on each side of the separator and have many to many relationship xref table to indicate what combinations are valid. For instance you could assign values on the left as Bird=1, Mammal=2, Insect=3 and on the right as Eagle=1, Sparrow=2, Rabbit=3, Beetle=4. The xref table would have 2 collumns and the rows would have the values 11, 12, 23, 34.
Avoid fields that depend on partial primary keys. Such fields make bulk update queries complicated. All fields in a table row should depend on the full primary key of the table.
Avoid derived columns in transaction (OLTP) oriented databases. Derived columns in OLTP databases negitively affect performance. Derived columns are nessesary in analysis oriented (OLAP) where lots of summation is the rule. In OLAP databases derived columns are likely to improve performance.
Designing databases I generally try to follow these rule. Sometimes in designing mixed use db's you need to apply the rules with varying degrees of rigor.
Assign datatypes to fields with care. Assigning an inappropriate datatype can cause issues during application development. Changing a field datatype after the fact can cause headaches rewriting some of the application code.