If your database is shared by more than application, then this is more a database design issue than it is a Yii issue. Speaking strictly from the database perspective first, your alternative 2 is more normalized. For example, if a product name has to be a book or a course, but can’t be both, that business rule is harder to enforce with two separate, complete tables.
In a shared database, ideally you enforce this type of integrity at the database level using constraints, not with application code, although the application in this case should be designed to surface the exceptions thrown by the database. However, this is not an issue if your application is the only one that manipulates the data because, for example in Yii, you can use rules to enforce your data policy.
If the data is not too large and you have use cases that manage the products together, you can consider a 3rd (less attractive to DB purists) design, i.e. put all the columns in a single table, making specific columns conditionally required based on the product type. In your Yii code, you could then abstract a base model with required properties and rules for the common fields and extend that model with specific properties, rules and other functions for each product type, i.e.,
class Product extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'Products';
}
public function rules()
{
return [
[['id', 'name', 'description'], 'required'],
/* more common rules */
];
}
/* etc... */
}
class Book extends Product
{
public function rules()
{
return [
[['isbn', 'nor_pages'], 'required'],
/* more Book rules */
];
}
/* etc... */
}
class Course extends Product
{
public function rules()
{
return [
[['duration'], 'required'],
/* more Course rules */
];
}
/* etc... */
}
Hope this gives you an idea or 2.
Best,
Joe