Laravel - Split Users DB Table: Why It's (Not) Bad?

Поделиться
HTML-код
  • Опубликовано: 5 июл 2024
  • I often hear an argument that there can be too many fields in the "users" DB table, so it's worth splitting it into two tables with the relationship. Let's take a look at one example, and I will share my thoughts.
    Source of Laerx: github.com/codenteq/laerx
    My course "How to structure DB in Laravel": laraveldaily.teachable.com/p/...
    - - - - -
    Support the channel by checking out my products:
    - My Laravel courses membership: laraveldaily.teachable.com/p/...
    - Laravel QuickAdminPanel: bit.ly/quickadminpanel
    - Livewire Kit Components: livewirekit.com
    - - - - -
    Other places to follow:
    - My weekly Laravel newsletter: bit.ly/laravel-newsletter
    - My personal Twitter: / povilaskorop
  • ХоббиХобби

Комментарии • 70

  • @LearnWithHibaNoor
    @LearnWithHibaNoor 2 года назад +8

    Very genius overview. 👏
    Personally I'm fan of database structure tutorials.

  • @lukasdurcak7033
    @lukasdurcak7033 2 года назад +16

    From a database point of view, that's fine. Maybe exactly as it should be. The problem here is eloquent. In traditional approach you can write one sql query that covers lots of table and result that into one object. The lack of this approach should be criticized, not the design of db tables.

    • @sergiocasao
      @sergiocasao 2 года назад +5

      the design of the tables is criticized because it's using laravel and he is reviewing a Laravel project with that database design. if he was criticizing only the database design this would be a fair comment.

    • @lukasdurcak7033
      @lukasdurcak7033 2 года назад +3

      @@sergiocasao I agree with you. The reason why I considered it important to write a comment is that there are many people who do not have the necessary knowledge and learn it as a rule.

    • @user-si3nz1dd9w
      @user-si3nz1dd9w 2 года назад +1

      It's not even a problem in the first place since Eloquent has the necessary tools to properly execute the performant queries. In this particular case, you have options to use eager loading or use subqueries with addSelect(), or just go with joins. Eloquent handles all that, too. The problem here is the app design, not he tool.

  • @kaf83
    @kaf83 2 года назад +5

    The db structure was perfect. Its the query that was wrong. It's become fashionable to not use joins in laravel. I don't know why. There seems to be a preference for multiple small and simple queries over one large and slow one. Which is fine. But most large and slow queries can be optimised to be just as fast or faster than multiple small queries. It just takes good db engineering knowledge. Which most laravel devs seem to lack.
    Just join the info table and enjoy querying the fields with the same ease and speed as if it were on the user table. One to one joins are the easiest. No reason to avoid them.

  • @amrqawasmeh
    @amrqawasmeh 2 года назад

    Very useful information 👌 keep it 💯

  • @smith4591
    @smith4591 2 года назад

    The way I suggest to do this is keep using the user information on the normal `user` table. So you wont duplicate the query when you type auth()->user() . For user authentication (user id, email, and password) you can use a separate table.

  • @cyeg12c
    @cyeg12c 2 года назад

    Nice topic, 👍

  • @JenuelDev
    @JenuelDev 2 года назад

    thanks mate for the tip

  • @sergiocasao
    @sergiocasao 2 года назад +1

    Love database structure tutorials using Laravel! I wonder if you have a video explaining the best way to structure a database where users can have different roles (i.e. buyers or sellers) and you need to store different data for each.

    • @LaravelDaily
      @LaravelDaily  2 года назад

      Not specifically, can you give a specific example of the list what those fields would be? Could be a good topic for a future video.

    • @sergiocasao
      @sergiocasao 2 года назад +1

      @@LaravelDaily for example i would like to create an uber like app where i have drivers and users, users can take a drive and rate the driver also drivers can have their bio, license number, years driving, rating and just them can have relations like to the car the are driving and so on... both drivers and users should be able to login so i'm not sure if i should store drivers and users in the same users table or create a drivers table associated with the users. If I go with the first option how can I make sure the driver of a ride is effectively a driver and not a simple user?

  • @SilverPaladin
    @SilverPaladin 2 года назад +1

    I would do this with optional data, and then I would probably use a key/value store for each optional field. Most efficient!

  • @user-cf5uf7vf2g
    @user-cf5uf7vf2g 2 года назад

    i feel this too, some field needed to place inside users table instead of user_etc for ease of query. But this method not good for upgrade laravel or reusability, BUT upgrade is once upon of time, i pick normalize user table.

  • @zHqqrdz
    @zHqqrdz 2 года назад +6

    Just add a $with in the User model, and you'll get the ->info loaded every time in one query only, since it's used almost 100% of the time.
    While this project doesn't look very serious and there's a ton of improvement that can be made, splitting the user table in this case doesn't seem very concerning.

    • @LaravelDaily
      @LaravelDaily  2 года назад +3

      Well, it's not used 100% of the time, only in a few places, so $with would load too much data for all the other cases. Agree that this project is not a good example, but that's exactly why I took it for review.

    • @mityukov
      @mityukov 2 года назад

      I think you don't need $with here. Yes, you will probably need current user' info on pretty much every page, but there could be places, where more than one user is queried, and not for all of them there really a need of loading info (and where it's needed - you just explicitly add ->with('info').
      As for the current user - i think it's ok to have one extra query on all the pages.

  • @gebruikersnaam999999
    @gebruikersnaam999999 2 года назад

    I like to have all required fields in the users table (name, password, photo, username, etc) and all optional fields in a profiles table (bio, company_name, etc.)

  • @taranemmolla
    @taranemmolla 2 года назад

    Database structure tips🎉🧨

  • @soniablanche5672
    @soniablanche5672 2 года назад

    is there a way to load both at the same time in the User model constructor for example ?

    • @LaravelDaily
      @LaravelDaily  2 года назад

      $with = ['info']; but you need to be careful to always load too much info

  • @_saurabhshah
    @_saurabhshah 2 года назад +1

    We could just cache the user object and purge the cache on every update event for that particular user. So if caching is used, it really doesn't matter if there are multiple tables or a single table. Right?

    • @LaravelDaily
      @LaravelDaily  2 года назад +7

      In theory, yes, but you have to be really careful with cache and its refreshing. And I don't think storing all data for all users in the cache is a good idea.

  • @stevepalmer4521
    @stevepalmer4521 2 года назад +2

    Won't auth()->user()->info-> result in a DB lookup the first time, but then any subsequent uses will use cached data, so no more DB queries?
    Also, what's the drawback of having a table with lots of fields?

    • @LaravelDaily
      @LaravelDaily  2 года назад +2

      Table with lots of fields will be slower to INSERT data, with also risk that developers would do "Select * from table" and blindly download too much data.
      With cached data, it depends on how you use that auth()->user()->info in your code, the example I've shown is just one of the examples.

    • @sarvsarv6349
      @sarvsarv6349 2 месяца назад

      when you write user->info-> just the first time eloquent query for info table. also if you dont want this approach and want query each time you can write user->info()->

  • @joseloguercio7934
    @joseloguercio7934 2 года назад +2

    What about using only a json column ? I usually use this way in all my projects because my clients always ask me for different fields and dynamic or extra fields for their users and instead of creating fields in the database I only use a json type field, in this way I can add different fields without doing a migration for each one. What do you think ? it worth?

    • @LaravelDaily
      @LaravelDaily  2 года назад +1

      If in your case it makes sense, and you don't have problems querying the data from there, then it works for you :)

    • @JoseDlucca
      @JoseDlucca 2 года назад +1

      I think json columns work fine most of the times. What I don't like it is that your lose the ability to use fk in cases where you have relationships inside the json

    • @oussama40612
      @oussama40612 2 года назад +1

      Sounds hacky and like a hassle to maintain

    • @IvanRandomDude
      @IvanRandomDude 2 года назад +1

      Seems like you need document database lol

  • @hadidagher9443
    @hadidagher9443 2 года назад

    What about a morph relation on the User model that points to additional fields from another model, Is it a viable option? MobileUser, StoreUser..etc

    • @LaravelDaily
      @LaravelDaily  2 года назад +2

      Sounds like unnecessary over-complication, but is it viable or not would need to actually try it and measure the results.

  • @juniordev4190
    @juniordev4190 2 года назад +3

    I use json field for dynamic data. Is it good to use json field for dynamic data. Imagine you are building google form builder or survey builder, how would you save all the data, what will be your table structure?

    • @LaravelDaily
      @LaravelDaily  2 года назад +1

      I guess this is worth another video :)

  • @pauloclara4764
    @pauloclara4764 2 года назад

    good morning... I have an application with a database that will have about 100 tables... is that too much or should I split it into two related databases? Thanks

    • @LaravelDaily
      @LaravelDaily  2 года назад +3

      Do you have performance problems? If not, it's fine :)
      There's no "too much", there are specific problems that you need to solve and then optimize specific functionality related to it.

    • @pauloclara4764
      @pauloclara4764 2 года назад

      @@LaravelDaily for now no working problems...thanks

  • @antonyjere
    @antonyjere 2 года назад +2

    But what if this structure is what they want? I mean, this can be also improved without changing the DB structure, while still having this maintainable, clean IMO structure. Personally I like it, why not?
    For example in your first example in the Controller, they could just use $user->info once, on a variable like $userInfo = $user->info and just use this variable below. Problem solved for this one, now it will run just one query to get the user info.
    About taking the photo on the layout, what would you suggest? Well, caching some specific user->info fields or the whole info modelis they only way I think.
    And about the middleware, the same, this should be cached.
    And "forget" from cache each time a user information gets updated. (using Observers)
    My whole point is, what would you suggest if they really want this structure, for whatever reason. I would really like to hear your opinion on this, but with the current structure.

    • @LaravelDaily
      @LaravelDaily  2 года назад +1

      So you're saying I should make a suggestion on how to find complex workarounds for the structure which they chose to be more complex themselves? Sorry that's not my way of thinking :)

    • @antonyjere
      @antonyjere 2 года назад

      How would you face this problem if the DB had already one million users, as a random example of course. You would change the structure and somehow backfill the new fields?

    • @LaravelDaily
      @LaravelDaily  2 года назад +1

      Yes, because I would care about the future of this project, and not a temporary workaround fix.
      But, most likely, I would refuse to work on such project :)

    • @antonyjere
      @antonyjere 2 года назад

      @@LaravelDaily haha makes sense. thank you man. Continue the excellent work. Sorry for too many questions, but you know I try to keep this interesting, for both of us. Just saying "excellent nice" and things like that doesn't drive anywhere :)

  • @AdiGunawan1
    @AdiGunawan1 2 года назад

    Performance or Aesthetic Functionality ? We must have both

  • @rihulfaakbar2261
    @rihulfaakbar2261 2 года назад +1

    So, dont separate fields that often used for queries?

  • @sergeysaharov5750
    @sergeysaharov5750 2 года назад

    It seems to me that there is no problem with database (with approach to separate "service data" and "profile data"), there is a problem with the code itself and one big flat table not solve the problem but creates new

  • @p30mehrdad
    @p30mehrdad 2 года назад +4

    what about a json field in same table?

    • @LaravelDaily
      @LaravelDaily  2 года назад +3

      Also possible, but I'm not a big fan of json fields. They kinda ruin all the purpose of using DB and its capabilities. But they may work, in some cases.

    • @arashpirhadi1326
      @arashpirhadi1326 2 года назад +1

      integer is super fast and imagine u wanna convert (status_id, month_id, company_id,....) to json and put these data in a single column in database. I think its against the rule of database engine and in big data for CRUD operations the program will die.

    • @harshmudhar96
      @harshmudhar96 2 года назад +1

      If you're not going to query based on a json object, it's a pretty good option. As a rule I don't put in stuff that is better suited for a relational DB, usually references/keys.

    • @p30mehrdad
      @p30mehrdad 2 года назад

      @@arashpirhadi1326 understand, You are definitely right

  • @PunyFlash
    @PunyFlash 2 года назад

    I'm not sure, but the way Laravel's bindings works, when you call auth()->user(), you get the same model instance every time, so when you call auth()->user()->info multiple times, the info relation already eager-loaded, so there are no extra queries to the database. At least, this is how facades and singleton bindings works, but I'm not sure how it's inside Auth facade, need to inspect more detailed

  • @ailtondevesse4738
    @ailtondevesse4738 2 года назад

    i noticed you wrote "companyId" and not "company_id" isn't it good practice to use the second approach, use underscores ?

    • @sergiocasao
      @sergiocasao 2 года назад

      it's better to use underscores

    • @LaravelDaily
      @LaravelDaily  2 года назад +2

      No, good practice is company_id. I didn't write that code, it's not mine, I took it from one open-source project, I mentioned it in this video.

    • @ailtondevesse4738
      @ailtondevesse4738 2 года назад

      @@LaravelDaily my bad I missed that part, thank you 🙏🏽

  • @jessedeboer2301
    @jessedeboer2301 Год назад

    Oké so why not create a method in the user model that eager loads the info with the user. Then you only have to call that method on the places needed, you’d also could give it a param to only() get the necessary fields?
    return $this->settings()->with('user');

  • @giacomogaravaglia6742
    @giacomogaravaglia6742 2 года назад

    why not load a singleton in a ServiceProvider with all the info? This can save performances, i suppose. Of course, your solution is more "standard"

  • @chlouis-girardot
    @chlouis-girardot 2 года назад +1

    This project is not a very good example to follow 😖
    But nice topic, thanks Sir 🙏

    • @LaravelDaily
      @LaravelDaily  2 года назад

      I often take projects for review not for people to follow those projects, but specifically for that reason - for me to work on some improvements.

    • @oussama40612
      @oussama40612 2 года назад

      That routes file is a mess

  • @kendinesponsor
    @kendinesponsor 2 года назад

    Asın bayrakları

  • @pabgrmc
    @pabgrmc 2 года назад

    Maybe this could be a nice feature for the next Laravel release: map the user Eloquent model (or any model) to get data from two tables instead of just only one.

    • @LaravelDaily
      @LaravelDaily  2 года назад

      You can suggest that as a pull request, it's an open-source framework :)

  • @span4639
    @span4639 2 года назад +4

    Splitting a table because it's aesthetically more pleasing to the eye does not make it a valid argument. Why burden the db with an extra query every time a user's info needs to be fetched? Totally against it since it doesn't produce any tangible benefit.

    • @oussama40612
      @oussama40612 2 года назад

      I agree, joins are expensive and should be avoided when possible

  • @NoName-oh9fh
    @NoName-oh9fh 2 года назад +1

    Ты же русский? Акцент похож очень

    • @CJIu3eHb
      @CJIu3eHb 2 года назад

      И на угрюмую рожу - тоже русский. Тут нас ни с кем не спутаешь. :) Но ему сейчас лучше не акцентировать на этом внимание.

    • @NoName-oh9fh
      @NoName-oh9fh 2 года назад

      @@CJIu3eHb и правда😂