I keep messing up 1NF

前端 未结 4 1464
逝去的感伤
逝去的感伤 2021-01-25 07:51

For me the most understandable description of going about 1NF so far I found is ‘A primary key is a column (or group of columns) that uniquely identifies each row. ‘ on www.phlo

相关标签:
4条回答
  • 2021-01-25 08:12

    On 1NF, from wikipedia, quoting Date:

    According to Date's definition of 1NF, a table is in 1NF if and only if it is "isomorphic to some relation", which means, specifically, that it satisfies the following five conditions:

    • There's no top-to-bottom ordering to the rows.
    • There's no left-to-right ordering to the columns.
    • There are no duplicate rows.
    • Every row-and-column intersection contains exactly one value from the applicable domain (and nothing else).
    • All columns are regular [i.e. rows have no hidden components such as row IDs, object IDs, or hidden timestamps].

      —Chris Date, "What First Normal Form Really Means", pp. 127–8[4]

    First two are guaranteed in any modern RDBMS.

    Duplicate rows are possible in modern RDBMS - however, only if you don't have primary keys (or other unique constraints).

    The fourth one is the hardest one (and depends on the semantics of your model) - for example your field Customer_address might be breaking 1NF. Might be, because if you make a contract with yourself (and any potential user of the system) that you will always look at the address as a whole and will not want to separate street name, street number and or floor, you could still claim that 1NF is not broken.

    It would be more proper to break the customer address, but there are complexities there with which you would then need to address and which might bring no benefit (provided that you will never have to look a the sub-atomic part of the address line).

    The fifth one is broken by some modern RDBMs, however the real importance is that your model nor system should depend on hidden elements, which is normally true - even if your RDBMS uses OIDs internally for certain operations, unless you start to use them for non-administrative, non-maintenance tasks, you can consider it not breaking the 1NF.

    0 讨论(0)
  • 2021-01-25 08:19

    use Object Role Modelling (say with NORMA) to capture your information about the design, press the button and it spits out SQL.

    This will be easier than having you going back and forth between 1NF, 2NF etc. An ORM design is guaranteed to be in 5NF.

    Some notes:

    • you can have composite keys
    • surrogate keys may be added after both conceptual and logical design: you have added them up front which is bad. They are added because of the RDBMS performance, not at design time
    • have you read several sources on 1NF?
    • start with plain english and some facts. Which is what ORM does with verbalisation.

    So:

    1. A Customer has many pizzas (zero to n)
    2. A pizza has many toppings (zero to n)
    3. A customer has an address
    4. A pizza has a base
    5. ...
    0 讨论(0)
  • 2021-01-25 08:28

    I'd use some more tables for this, to remove duplication for customers, orders, toppings and pizze:

    Table: Customer

       Customer_id
        Customer_name
        Customer_name
        Phone
        Promotion
        Blacklist Y or N
        Customer_address
        ZIP_code
        City
        E_mail
    

    Table: Order

    Order_id
    Order_date
    Customer_id
    Delivery_zone
    Deliveryguy_id
    Deliveryguy_name
    Delivery Y or N
    

    Table: Order_Details

    Order_ID (FK on Order)
    Pizza_ID (FK on Pizza)
    Amount
    

    Table: Pizza

    Pizza_id
    Pizza_name
    Size
    Pizza_price
    

    Table: Topping

    Topping_id
    Topping_name
    Topping_prijs
    Availabitly
    

    Table: Pizza_Topping

    Pizza_ID
    Topping_ID
    

    Pizza_topping and Order_details are so-called interselection tables ("helper" tables for modelling a m:n relationship between two tables).

    Now suppose we have just one pizza, some toppings and our customer Billy Smith orders 2 quattro stagione pizze - our tables will contain this content:

    Pizza(Pizza_ID, Pizza_name, Pizza_price)

      1 Quattro stagioni 12€
    

    Topping(Topping_id, topping_name, topping_price)

      1 Mozzarrella 0,50€
      2 Prosciutto 0,70€
      3 Salami 0,50€
    

    Pizza_Topping(Pizza_ID, Topping_ID)

     1 1
     1 3
    

    (here, a quattro stagioni pizza contains only Mozzarrella and Salami).

    Order(order_ID, Customer_name - rest omitted)

    1 Billy Smith
    

    Order_Details(order_id, Pizza_id, amount)

    1 1 2  
    

    I've removed delivery ID, since for me, there is no distinction between an Order and a delivery - or do you support partial deliveries?

    0 讨论(0)
  • 2021-01-25 08:29

    The strengths of relational databases come from separating information into different tables. One useful way of looking at tables is first to identify as entity tables those concepts which are relatively permanent (in your case, probably Pizza, Customer, Topping, Deliveryguy). Then you think about the relations between them (in your case, Order, Delivery ). The relational tables link together the entity tables by having foreign keys pointing to the relevant entities: an Order has foreign keys to Customer, Pizza, Topping); a Delivery has foreign keys to Deliveryguy and Order. And, yes, relations can link relations, not just entities.

    Only in such a context can you achieve anything like normalization. Tossing a bunch of attributes into one singular table does not make your database relational in any meaningful sense.

    0 讨论(0)
提交回复
热议问题