0

I am learning postgres/SQL and am wondering what the best approach is here.

I have an invoice db design that has recipients, drafts, items. Drafts are the invoices, items are the lines on the invoices, and recipients are who it's going to.

When creating an invoice I have to insert into each table accordingly. Which approach is considered best practice?

There is this one where it's one giant complicated query.

db.query('
WITH new_recipient AS (
    INSERT INTO 
        recipients(...) 
    VALUES (...)
    RETURNING id AS recipient_id, user_id
), new_draft AS (
    INSERT INTO drafts(user_id, recipient_id)
    SELECT user_id, recipient_id FROM new_recipient
    RETURNING id AS draft_id
)
SELECT new_recipient.*, new_draft.* FROM new_draft, new_recipient'
,[...])

OR:

  const data = await pool.query(
      `INSERT INTO recipients (...) VALUES (...) RETURNING *`,
      [....]
    );


const draft = await pool.query(
      `INSERT INTO drafts (recipient_id, ...) VALUES ($1, ...) RETURNING *`,
      [data.rows[0].recipient_id, ...data]
    );

I am inclined to use the second approach for readability and simplicity. Is there any reason one should use the first one instead? Perhaps performance is slower if you break it up into multiple queries?

2
  • I'd expect one recipient to buy from you more than once. So you won't always be inserting a new recipient when you create a draft. Sometimes that recipient will already be in your database. If that assumption holds, the second one makes more sense to me. Commented Feb 16, 2023 at 20:11
  • Your first option, with the CTE, could use just one level in the cte instead of two. And your second option has to run in transaction, don't forget BEGIN and COMMIT or you might end with half an invoice. Commented Feb 16, 2023 at 20:55

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.