views:

1489

answers:

6
+2  A: 

If a buyer can be a seller (and vice versa), why not have a single customer table with a set of flags for account type?

If books are unique (i.e. one copy of Moby Dick is viewed separate from another copy ... more like eBay than Amazon), then your book table could have a buyer and seller foreign key. Your store's simplest design is now down to two tables. For example:

Cust table
cust_id
name
is_buyer
is_seller

Book table
book_id
description
seller_cust_id
buyer_cust_id

Edit: I don't think this solution changes even if a single buyer/seller must have two accounts. You would just add the restriction in your app that a customer cannot be both a buyer and seller. The nice thing about one table is that you don't need to duplicate security/login/etc. logic ...

Edit 2: Also, if a buyer can buy multiple books, wouldn't it make more sense to have a shopping cart table that stores each book purchased by a buyer?

Jess
oh, no! they can't be. a buyer needs to create a seller account if he/she wants to sell somethin'.
artarad
I also disagree. According to the specs, you must have an extra account - where I would make the assumption that an account is atomic and should not share any data with other accounts.
Marcel J.
Sir Lantis, can you expand on what you mean by "account is atomic"? I looked up "Atomicity (database systems)" on Wikipedia, but their definition of atomic is regarding transactions (either "all occur" or "none occur").
Calvin
thanks both for the replies. @LucktLindy: the books are unique. what if a book has multiple offers? does ur model work?
artarad
agree with Calvin. I don't know too.
artarad
like your edits, thanks.
artarad
I meant atomic like in modular - that you can't mess with the internals if you are not inside. If a seller can't "be" a buyer (so says the spec), don't make it possible in the database design. Otherwise you'll need more constraints/integrity checks in DB or SW.
Marcel J.
Better design would be Account(id*, buyer_id, seller_id) + constraint that either must be null, BuyerRole(specific_data), SellerRole(specific_data). Let the other entities link to the roles instead of to the account.
Marcel J.
I see... That makes sense.
Calvin
+1  A: 

If I understand you correctly, the buyers will place offers before any seller does anything. Then a seller can accept one of the pending offers. I would add a buyer ID to the process (in fact, a process would be created when a buyer places an offer), as well as the book ID and the offered price. Once a seller then closes the deal, the process can be link to the seller with the sID field. This way a buyer could hold several simultaneous offers on different books.

Maurice Perry
that's it, you understood correctly Maurice. so my latest model could work?
artarad
As I said, I would move the offer to the process table, and I would also add a bID and a byID to it
Maurice Perry
thanks Maurice, this SO editor sucks, this is not my latest model as you see. many many thanks.
artarad
Do you plan to provide a catalog to the buyers (with info about the book's availability) ?
Maurice Perry
Still I don't know, my thought is to remove the book if no copy is available, coz the app will be a store for used books not new ones.
artarad
Then you will need an additional table to link the sellers and the books
Maurice Perry
can't I add the seller id to the book field? is it ok in a db design?
artarad
Yes, but in this case, if two sellers have the same book to sell, of if a seller has several copies of the same book to sell, there will be several rows in the book table for the same title. This would introduce redundancy.
Maurice Perry
really thanks Maurice, that;s a hard work to consider every aspect of the design :)
artarad
tell me about it
Maurice Perry
+1  A: 

Taking LuckyLindy's comment a step further, use a single Customer table, create a table called Order (probably akin to your Process table), and a table called OrderItem. Your Buyers and Sellers are all Customers ... if your Orders are strictly between two people then your Order table can contain buyer and seller fields. For each item in an Order, you have a tuple in OrderItem (with an ID back to Order to bind the group).

Customer    Order       OrderItem
--------    -----------   ---------
id          id (pk)       id
name        date          order_id (fk)
            buyer (fk)    book
            seller (fk)   price
            total

This is really a rudimentary example, but it's shaping up that your requirements could just use a common shopping cart design. There's lots of examples you can find by Googling.

Greg
thanks Greg, nice guide :)
artarad
+2  A: 

I think you need a domain model similar to the following:

Buyer(BuyerId, ... buyer details ... )
Seller(SellerId, ... seller details ... )
Book(BookId, ... book details ... )
Bid(BidId, BuyerId, BookId, Price, Expiry)
Offer(OfferId, SellerId, BookId, Price, Expiry

How it works is that a user (Buyer or Seller) can create a Bid or Offer as appropriate. So if you are a buyer you may start by searching through the Offers available. If you like one you may choose to accept it and proceed to checkout. Perhaps you don't quite like any of the Offers but one is close in price to what you want. You might create a Bid and have that sent to the creator of the Offer to consider.

Or if nothing is close to your requirements as a buyer you may create a Bid and leave it in the system for potential Sellers to browse/search and consider till time of expiry you have chosen.

I have added the Bid and Offer classes and I think their benefit is self explanatory. But if you would like some further explanation please feel free to leave a comment and I will respond. The Expiry fields are not necessary but most likely every Bid and Offer will have a time limit in which case you will need them.

I have increased the number of classes/tables, but I think you will find that your system becomes much easier to manage and extend.

Ankur
The more I look at it the more I realise it can be improved. You really ought to have a single User class and isBuyer/isSeller fields as suggested by LuckLindy, since many buyers will be sellers (as has been pointed out) and you don't want to reproduce data.
Ankur
artarad
no prob .... good luck!
Ankur
+1  A: 

Well, accoring to the specification I would make a few assumptions:

  • Buyers and Sellers need seperate accounts - so they have to be atomic and must not share data, hence we will have two tables.
  • A book is a real-world instance. So, if a seller wants to sell 3 books of "The Hobbit", that would result in 3 table-rows.
  • Hence the book might get to attributes: the seller (read-only) and the buyer. But this doesn't work with the "process" of waiting for incoming offers from buyers.
  • Since there might be "batches" of book-buyings it makes sense to create a AuctionProcess entity. Also I would add another Bid entity. This results in the following scheme.

    Seller(id*)
    Buyer(id*)
    Book(id*, seller_id)
    AuctionProcess(id*, book_id, winning_bid_id, end_date, start_date?)
    Bid(id*, process_id, buyer_id, price)
    

    winning_bid_id will of course be NULL until a winner is chosen by the buyer.

It is quite similar to (just noticed) Ankur's response, only with the addition of the winning_bid_id relation.

Marcel J.
thank you again. I really can't choose the best answer here, all helped.
artarad
A: 

It does seem a bit confusing, the datamodel, the object model, functional and non-functional specs and requirements - parts of each being being discussed. Keep the notation and design elements clean, clear and separate.