Both can be used, of course. One is the formally correct, the other can give more efficiency in the system, in addition to the differences already noted by the author of the question.
One table, several lines (wrong)
From the point of view of normalization, among those presented, the second model seems to be the most appropriate. In fact it is quite possible that neither it is right, ie I’m almost sure that strictly the second is wrong.
Two related tables (formally correct)
Probably the right one would be a third form keeping this table of plans without the plots and have an auxiliary table only with the plots. I cannot say whether this is the most correct because I do not know the whole real problem and the example shown is artificial to make such a statement, although there are indications that the most correct one would be the auxiliary table. The second form does not meet the correct normalization, and already breaks the first normal form (among the 6 currently known).
Normalization indicates that you cannot have redundant information, nor have information without completion. So if you have lines whose fields have the same information (not by coincidence) it is being redundant. pl_nome_plano
is clearly redundant, you can not create multiple lines with this same information being that it should be unique, is thinking to create many lines for a single item, this hurts the normalization and creates difficulties. So the second model would be not only inappropriate, but formally wrong. Only if adapting it to the auxiliary table would it be correct, and depending on the situation would be appropriate.
Single table, multiple fields (acceptable)
The first case can be perfectly acceptable as an exception to the rule, since although it is formally wrong, it does not create serious problems, and can compensate for its use if it needs efficiency (not always). Right must be a priority.
If everything is in one table, in one row you can take the data with less effort in the database and this is useful in some scenarios. The great disadvantage of this is that it needs to have a field for each possible plot and in most cases many of these plots will be null, which will take up some space (some Dbs have a very low cost, depends on the implementation of each one, but for a large volume of fields there will be space waste).
Depending on the database system adopted this could be put in a array of fields, or could simulate this array in a text field or blob. It is not so necessary, there are advantages and disadvantages in doing this.
This model has more Nosql face (which is actually the model that ignores relationships).
It’s easier to access the data directly, but you need to manipulate it in some situations, as the question already notes. But the relational model is not carefree, as it is also observed, and indeed can be even more laborious depending on the scenario.
Completion
The amount of lines themselves is no problem.
So to be clear, the fastest way tends to be the first model. The second one tends to be the second best case and the third one I exposed using auxiliary is only the third fastest, under typical conditions, the use of join
It’s usually the worst performance, so the myth has been created that Nosql is faster, comparing different things. Only the third way (which I defined) is formally correct.
The second example of the question has an error in the primary key, failed to include the portion number in it to give a single key. It would be something like this:
create table planos(
codkey (primary),
nome_plano varchar(80)
)
create table planos_parcelas(
codkey (primary),
item int (primary),
valor decimal(12, 2)
)
I put in the Github for future reference.
Note that you do not need foreign key, this is waste.
If you don’t want to violate any normal way it would have to be. Not always this should be priority, in many cases I would adopt the first model of the question.
I still don’t know if the model as a whole is totally correct. It is still confusing to have values of plots within the plans, for me the whole concept is wrong, but it may just be lack of enough information, or wrong nomenclature. Plans should not have values, but if there is a lack of explanation (not that it is relevant to the question problem, but may hide a more serious error in modeling), or it may be that this is not a plan, but the use of the plan, which is an account or something like that. But there may be a justification for it, I’m just speculating.
i edited my answer on an important detail about having plan id (pl_codkey ) and portion in the same table, this will give problem ;)
– Ricardo Pontual