Why You Should Replace Your Booleans With Timestamps

แชร์
ฝัง
  • เผยแพร่เมื่อ 13 ต.ค. 2024

ความคิดเห็น • 116

  • @tinrab
    @tinrab 2 วันที่ผ่านมา +43

    Hmm, maybe. I use "deleted" as a boolean and "deletedAt" as datetime, at the same time. At a previous job, we had both as well. I can't remember why both were needed. One thing you can do with booleans and not datetimes (i think) is sharding.

    • @-taz-
      @-taz- 2 วันที่ผ่านมา +13

      I've worked for billion dollar companies where that was the rule. Usually the sales people were very successful, and didn't know what they were doing when they hired a bunch of idiots to write their software.

  • @dhmacher
    @dhmacher วันที่ผ่านมา +15

    Database professional here: this is _great_ advice. Also, always verify your backups.

    • @aghileslounis
      @aghileslounis วันที่ผ่านมา

      what do you mean by verify your backups? Like test if they are not corrupted and actually contain the correct data?

    • @dhmacher
      @dhmacher วันที่ผ่านมา +1

      @@aghileslounis yes. Just because you can make a backup does not mean it restores ok. There could be database corruption (that could get silently written to your backups), storage hardware bugs, disk errors, or even just incorrectly set up backup jobs.

  • @planesrift
    @planesrift 2 วันที่ผ่านมา +10

    I love date, it is the most universal format of all

  • @justusonuoha8224
    @justusonuoha8224 2 วันที่ผ่านมา +21

    I know companies that have audit tables that keep history of when fields got changed.

    • @MichaelCampbell01
      @MichaelCampbell01 2 วันที่ผ่านมา +4

      This is a very old technique; my job in the 1990's was doing this with triggers in Sybase. Any update to a row wrote the entire row to a "shadow" table before the change with a timestamp of the update. It is a very early kind of an "event streaming", immutable database scheme.

    • @-taz-
      @-taz- 2 วันที่ผ่านมา +1

      @@MichaelCampbell01 I'm not sure I'd say it was early event streaming, but more like the kind of kludges that event streaming tried to address by using a cleaner idiom.

    • @m12652
      @m12652 วันที่ผ่านมา +1

      People still ask for audit trails, especially on safety systems etc.

    • @-taz-
      @-taz- วันที่ผ่านมา +1

      ​@@m12652 The audit trail should be designed into the database, not sometning tacked on. Although I swear that 90% of people who think they're database experts would just overwrite a timestamp without giving it a thought. Any idiot can use a database. The job is to design a database so when the client asks for some obvious bit of information 4 years from now, it will already be in the database. Not "oh, you didn't say you wanted to be able to track the previous time this thing happened."
      It's so stupid it's like when Google Maps says "turn right" and you crash into a car. Hey, you didn't say "turn right unless there's a car in the way!" That's how dumb most developers are, I think (after 30 years of this... and things keep getting worse not better!).

    • @m12652
      @m12652 วันที่ผ่านมา +1

      @@-taz- lol you sound like you've not been doing this long. What makes you think audit trails are generally just tacked on? "Do you want an audit trail with that?" is always one of my first questions.
      As for most developers being dumb, are you sure you're not just talking about yourself?
      Personally, I'm old by the way, I built my first database on an Amstrad 8512, and the one thing I've noticed in the 30 or so years since... people that make general assumptions and big angry statements about other people being dumb are usually either talking about themselves or trying to distract people from their own terrible code.

  • @ChristopherBriddock
    @ChristopherBriddock 23 ชั่วโมงที่ผ่านมา +1

    I would use both a timestamp and also a boolean for soft deletions and a DeletedBy field to capture their User ID. For modified and created, just using a timestamp with a User ID field works for me. In C# I use three ValueObjects, EntityCreationStatus, EntityModificationStatus and EntityDeletionStatus to save on duplicating the code via an interface, e.g. ISoftDeletableEntity. I also like using Temporal tables, which saves any modifications in a history table, with PeriodEnd and PeriodStart fields. Downside is you would have to do this manually in Postgres + EF Core, where SQL Server + EF Core, you can do this with a config option on each entity.

  • @StefanoV827
    @StefanoV827 วันที่ผ่านมา +3

    That's a good advice but not always if we talk about cardinality. With a boolean the cardinality is 2 and you dont need an index to search for that field most of the times. With a timestamp you need to calculate not just the byte you showed, but the index space + the little amount of time wasted during insert/update because of the index.
    So, yes good advice but never abuse it. If you dont need the time of the boolean, just use a boolean

    • @saadzahem
      @saadzahem วันที่ผ่านมา

      What is cardinality?

    • @StefanoV827
      @StefanoV827 วันที่ผ่านมา +3

      @@saadzahem cardinality is how many unique values are on that column. With low cardinality you can usually avoid index. For example boolean values (tinyint). With high cardinality, SQL needs an index to search more efficiently and faster. So timestamp are always different generating high cardinality and forcing you to use index, while boolean is always cardinality 2.

  • @omkarstha
    @omkarstha 2 วันที่ผ่านมา +9

    $exists for mongodb, also rephrased as sexists

  • @EmmanuelOdii80
    @EmmanuelOdii80 2 วันที่ผ่านมา +17

    Good idea!
    But another caveat to this approach is that the column MUST be nullable.
    Take for instance you would want to have FALSE be the default value of the column, it's impossible to fix that with a timestamp :)
    Wdyt?

    • @joonaskrohn6785
      @joonaskrohn6785 2 วันที่ผ่านมา +4

      False is already the default value, since null maps to false in this case.

    • @EmmanuelOdii80
      @EmmanuelOdii80 2 วันที่ผ่านมา +1

      @@joonaskrohn6785 Agreed.
      We just have to think about it properly, hehe.

  • @jigani99
    @jigani99 วันที่ผ่านมา +2

    I think this solution only accounts for the positive state. For a Boolean field that can change multiple times from false to true and then back to false. The timestamp trick won't be able to account for the timestamp of a field that was true and later set to false

    • @witchmorrow
      @witchmorrow วันที่ผ่านมา

      you can just set the field to be `null` again when the condition becomes false in your code

    • @jigani99
      @jigani99 วันที่ผ่านมา +1

      @@witchmorrow I agree but there's no timestamp information of when the field was set to null again

  • @soverain
    @soverain 2 วันที่ผ่านมา +4

    More like this please!

  • @XavierGoncalves89
    @XavierGoncalves89 วันที่ผ่านมา

    I implemented by myself a few months ago while working on an angularjs codebase, in order to detect if an object’s properties had changed

  • @marcusradell7544
    @marcusradell7544 2 วันที่ผ่านมา +1

    Nice way to dip your toes in event sourcing 👍

  • @ucretsiztakipci6612
    @ucretsiztakipci6612 วันที่ผ่านมา +1

    It's faster and cheaper to maintain boolen in a high scale. Do some tests in 100m or more for reporting. Specially in real time.

  • @mattwandcow
    @mattwandcow 2 วันที่ผ่านมา

    This is a useful idea to know about. Thanks!

  • @peanut-butter-e1r
    @peanut-butter-e1r วันที่ผ่านมา +2

    bro has built-in spring inside neck that move his head all the time

  • @pomprocks
    @pomprocks วันที่ผ่านมา +3

    How about nameChangedAt, nameSetAt, nameRemovedAt, ageChangedAt, emailChangedAt? IMO if you want that data its better to just use the boolean and track it with another system.

    • @TheSliderW
      @TheSliderW วันที่ผ่านมา +2

      Yes. Dont fill up your table with useless columns that happen to only get used once or twice in a decade. What a waste of ressources. This is what logs are made for.

  • @CptWashu
    @CptWashu วันที่ผ่านมา

    The other use case is tables that have critical data. But you'd have to check the cost/ease trade off

  • @Noceo
    @Noceo 2 วันที่ผ่านมา +1

    In some (granted rare) cases this could impact performance negatively. It’s not just extra space in the DB. This requires extra computations every time you want to check e.g. if a user is deleted.
    But it’s definitely a useful tip, if applied with some thought.

    • @m12652
      @m12652 วันที่ผ่านมา

      Not at all... if the field is null it is false, not null it's true... what extra calcs? In your example you would have a deletedDate as opposed to a deletedBoolean. Much more useful.

  • @ArielZ13
    @ArielZ13 วันที่ผ่านมา +4

    Why not just updatedAt column?

  • @ДмитрийКарпич
    @ДмитрийКарпич 22 ชั่วโมงที่ผ่านมา

    Actually, it`s a strange idea. If you need timestamps for logging only, just add another table for logging. And I`m not database pro, but it seems it`s a terrible decision for indexes and complex indexes at first place.

  • @trappedcat3615
    @trappedcat3615 2 วันที่ผ่านมา +2

    Sound like the database simply needs a single timestamp for all events 😅

  • @moggedau
    @moggedau 20 ชั่วโมงที่ผ่านมา

    This isn't feasible in a large application - use a logger and create a audit log function. Then at any part of the application you can log x user did y something at this date time.

  • @MrNickP
    @MrNickP 2 วันที่ผ่านมา +3

    I can see a few uses for this but overall definitely not something to do by default.

    • @-taz-
      @-taz- 2 วันที่ผ่านมา +2

      That's right. We need to model the data with purpose. Don't add complexity "just because it might make debugging easier." Debugging is what people do after they've already screwed up. It's like "quality control" in factories 80 years ago: eventually discovered to be pure waste.

    • @m12652
      @m12652 วันที่ผ่านมา

      The fact is though a lot of people use booleans when a nullable date would be much more useful... or worse use both eg closedDate and closedBoolean. Not because they're dumb, it was fairly standard in a lot of places years ago because on paper they would tick a box and date it.

    • @-taz-
      @-taz- วันที่ผ่านมา

      @@m12652 To me a nullable date or nullable anything seems even less appealing than a Boolean.

  • @AustinCameron
    @AustinCameron 2 วันที่ผ่านมา +2

    archived_at, deleted_at, sent_at

  • @RalfTenbrink
    @RalfTenbrink 2 วันที่ผ่านมา

    What a great tip. Thanks

  • @creatorsremose
    @creatorsremose วันที่ผ่านมา +1

    Sure but why are you crediting Vic when it was Swizec or introduced the idea? Vic just made a meme out of it.

    • @adambickford8720
      @adambickford8720 วันที่ผ่านมา

      I promise you the idea is older than that.

  • @marcuss.abildskov7175
    @marcuss.abildskov7175 วันที่ผ่านมา

    I've been using both booleans and timestamps to keep track of a field

    • @witchmorrow
      @witchmorrow วันที่ผ่านมา

      seems like you probably only need the timestamp

    • @marcuss.abildskov7175
      @marcuss.abildskov7175 วันที่ผ่านมา

      @@witchmorrow sure, I could add virtual getters to my entities that returns booleans.

  • @Neckhawker
    @Neckhawker 2 วันที่ผ่านมา +9

    or you just use logs

    • @-taz-
      @-taz- 2 วันที่ผ่านมา

      That's less bad because it doesn't add extra complexity to the database. Software quality can practically be measured by the number of logs, inversely. In 3.5 years of working at one company, there was only one log, and that's for a critical error that took place after a more serious critical error, because there was no way left to recover. No software person could find anything useful to do, with a combined 100 years of C++ experience, so it bubbled up to the dept. head, who said to "log it." That guy was an idiot who got fired for some HR nonsense a month later anyway. If there's a fact that matters to the enterprise, put it in a database or fire off some event. My most recent two companies have been the worst I've ever seen in 30+ years. We're swimming in logs and someone says "log it" at least every 3 days.

    • @CarnesSurefire
      @CarnesSurefire 4 ชั่วโมงที่ผ่านมา

      @@-taz- logs can be rotated/deleted. There's no need to store log-level data in a database unless that data is actively integrated into the app. Not sure why you're saying that you can store some data in a database but can't log the exact same info...

    • @-taz-
      @-taz- 3 ชั่วโมงที่ผ่านมา

      ​@@CarnesSurefire If the information is important to the enterprise, it goes in the database. Logs are for, I don't know, system admins in the 1970s? I'm not telling anyone to use logs ever. It's like the saying "when there's smoke there's fire." "When there are logs there are idiots writing software."

    • @CarnesSurefire
      @CarnesSurefire 3 ชั่วโมงที่ผ่านมา

      @@-taz- now you have to give your most junior devs access to prod data just to debug minor issues. Logs are also designed to be immutable and not required for the system to function. Putting log level info into the database is 1990s software design.

    • @-taz-
      @-taz- 2 ชั่วโมงที่ผ่านมา

      @@CarnesSurefire I'm not telling you to out log level data into the database. I just got through writing that you put only the information that matters to the enterprise. If you way of understanding your software is to sift through logs, well, I don't what you're even thinking. I didn't think that way when I was a kid, or in school, nor did I read it in a software engineering book.

  • @luisrodrigues6211
    @luisrodrigues6211 วันที่ผ่านมา

    How about the timestamp running out by 2039? what would be the advisable thing to do now to minimize it's impact?

  • @joel-rg8xm
    @joel-rg8xm วันที่ผ่านมา +1

    sounds logic, reasonable and convenient for a 300,000 records table, or isn't it?

    • @Naej7
      @Naej7 8 ชั่วโมงที่ผ่านมา

      What about a 16 Billions records table ? :^)

  • @danielschwartz516
    @danielschwartz516 วันที่ผ่านมา

    good topic!

  • @JimfromIndy
    @JimfromIndy 2 วันที่ผ่านมา

    Interesting idea.

  • @culturehyena
    @culturehyena 21 ชั่วโมงที่ผ่านมา

    If you need this level of auditing, you might be better off moving towards event-based systems?

  • @lsaavedr
    @lsaavedr 2 วันที่ผ่านมา

    thanks! I ❤ tricks like that!

  • @kalligatorGR
    @kalligatorGR วันที่ผ่านมา

    So at the end you still need the boolean, the difference being you now have to generate it every time instead of having it readily available in your db. Doesn't sound that good of an idea.

  • @pixelgoat_
    @pixelgoat_ วันที่ผ่านมา

    What about using a jsonb of specifically using Postgres. This type can also be efficiently indexed using GIN. u also wouldn’t need that extra options in the query example I used with two properties in the jsonb.

  • @montebont
    @montebont วันที่ผ่านมา +1

    Converting the timestamp to base 36 saves a lot of bytes...

    • @theguitarslinger1
      @theguitarslinger1 วันที่ผ่านมา

      Interesting thought... I (Chat GPT) did some math, and while it would be theoretically 10 bytes vs 6 bytes assuming 1 character = 1 byte, in practice, INTs are stored more efficiently than CHARs or VARCHARs in a database. In a typical SQL database, a Unix timestamp would be 4 bytes period. The same timestamp in base 36 would be 6 bytes, and actually 7-8 bytes with overhead. I ran it with base 52 (using both letter cases), and that did not save any bytes over the base 36. Strings also have more memory overhead when working with them, but there could be some minor memory savings depending on the environment. In Python, the base 10 timestamp would be 59 bytes, and the base 36 timestamp would be 55 bytes.
      You might have been joking and already known this, but I was curious :)

  • @cissedesign6358
    @cissedesign6358 วันที่ผ่านมา

    We've been doing that in Laravel for years now

  • @rickharold7884
    @rickharold7884 2 วันที่ผ่านมา

    Good idea.

  • @avid459
    @avid459 วันที่ผ่านมา +4

    don't do this, this doesn't work for most booleans where you have the possibility to toggle them back and forth.
    Your junior devs are bound to abuse them as well.

    • @m12652
      @m12652 วันที่ผ่านมา +1

      Depends on context, for example a deletedDate is more useful than a deletedBoolean....

  • @-taz-
    @-taz- 2 วันที่ผ่านมา +5

    That idea smells bad. It violates SRP and normal form. Timestamps in a database are usually a bad idea, too, such as a last sign-in time, when setting the time erases the previous sign in. What a joke! That should be stored every time.
    When the reason for something given is "for debugging purposes" we're talking about unconscious incompetence. If you have to watch some code execute to know what's going on, you've already fumbled the ball.

    • @ydkme-reborn
      @ydkme-reborn 2 วันที่ผ่านมา +1

      How does it violate SRP and Normal form? He's just replacing a Boolean with a timestamp.

    • @-taz-
      @-taz- 2 วันที่ผ่านมา +3

      @@ydkme-reborn I'm not sure why you're asking because these are both practically by definition.
      If a field that contains a timestamp is also serving as a boolean, it now has two responsibilities. The timestamp responsibility might be mostly useless, but the software is made more complex regardless.
      Having a nullable field at all violates normalization. Another smell. The normalized model would use another table to append data optionally. A 1:1 relationship could be used here. But if there's something that happens multiple times, a 1:N would actually model it correctly. And this is probably what's needed if you're tracking clicks, logins, etc. It can also be done pretty cleanly and naturally with event sourcing.
      There is even a third smell which might not be noticed by JS programmers -- the nullable value problem. By making things more complicated than necessary, errors become more probable.

    • @ydkme-reborn
      @ydkme-reborn วันที่ผ่านมา +2

      @@-taz- Thanks for the explanation. I don't think he's talking about tracking things like click though. That would definitely be a really bad idea.

    • @iaminterestedineverything
      @iaminterestedineverything วันที่ผ่านมา +1

      Remember that the use case being described here is to log when a user verified their email and when the user is deleted.. each event is only going to happen once so what is described in the video is a practical solution and creates an opportunity for analytics above a simple boolean. Over normalisation in circumstances like this is unnecessary and applying SRP here is pointless in my view, especially given you can translate the null/not null into a true/false in a query or view should you want to. If tracking changes on multiple columns in a row, I'd apply something like SCD type 2 or 4 (audit/history table)

    • @-taz-
      @-taz- วันที่ผ่านมา

      @@iaminterestedineverything Let's take the registration time / null. Well, in the meantime, before they register, there's a null. That also means there's definitely some mutable data necessity. (So there's a 4th smell.) If someone's going to register, then add a record to the registered collection, or insert into a registration table. Even better, they aren't even a User until they actually register. They're a UnregisteredUser or something like that. Where's the guidebook that user registration is allowed to have bad database design? Hehe.

  • @ydkme-reborn
    @ydkme-reborn 2 วันที่ผ่านมา +1

    Just use both

  • @lonleybeer
    @lonleybeer 2 วันที่ผ่านมา +1

    But.. cant you just log your data..?

  • @cb73
    @cb73 วันที่ผ่านมา

    This isn’t new at all. I’ve been doing this for years and it’s been a feature of Laravel/active record ORMs forever.

  • @yyanasolyah
    @yyanasolyah 2 วันที่ผ่านมา

    New guitar?

  • @marcscherzer
    @marcscherzer 2 วันที่ผ่านมา +1

    What about login? I don't think isLoggedIn can be replaced by loggedInAt (different meaning)

    • @imornar
      @imornar 2 วันที่ผ่านมา +4

      If u store these things in db, just stick with front-end

    • @EmmanuelOdii80
      @EmmanuelOdii80 2 วันที่ผ่านมา +1

      Where loggedInAt could mean the location where the user logged in from 😂

    • @m12652
      @m12652 วันที่ผ่านมา

      Actually isLoggedIn could easily be replaced by a nullable date. If it's populated they're logged in, if not... not.

    • @zxenon_
      @zxenon_ วันที่ผ่านมา

      @@EmmanuelOdii80 hehe 🤣🤣

  • @RobbPage
    @RobbPage วันที่ผ่านมา

    oh look, another game changer. the game sure changes a lot.

  • @Alex-KOX
    @Alex-KOX วันที่ผ่านมา

    What frawework is backend written in on video?

  • @nomadshiba
    @nomadshiba 2 วันที่ผ่านมา +2

    or make mutations witb transactions and keep the transactions history.

    • @-taz-
      @-taz- 2 วันที่ผ่านมา

      Much better.

  • @atulkumar_zip
    @atulkumar_zip วันที่ผ่านมา

    Cool

  • @howhello354
    @howhello354 วันที่ผ่านมา

    If you know Laravel, you already know this.

  • @sarahwbs
    @sarahwbs วันที่ผ่านมา

    How does this help with boolean that get toggled on and off??

  • @teenspirit8714
    @teenspirit8714 วันที่ผ่านมา +2

    such a stupid idea

    • @ChristianKolbow
      @ChristianKolbow วันที่ผ่านมา

      why? if you write such an assertion, you should also substantiate it

  • @andrii6292
    @andrii6292 วันที่ผ่านมา

    Reasonable. Thanks

  • @jamesford3282
    @jamesford3282 วันที่ผ่านมา

    stop making videos with clickbaits, I will do whatever I want

  • @АлександрГерасимов-с3щ
    @АлександрГерасимов-с3щ 2 วันที่ผ่านมา +2

    Before I watch: I doubt it will make anything meaningful as number (timestamp) will always be truthy

    • @EmmanuelOdii80
      @EmmanuelOdii80 2 วันที่ผ่านมา +3

      Not sure what you mean :/

  • @linela
    @linela วันที่ผ่านมา +2

    Another stupid advice 😮

    • @ChristianKolbow
      @ChristianKolbow วันที่ผ่านมา

      ok, then explain why. your comment is completely useless.

  • @nr7343
    @nr7343 วันที่ผ่านมา

    ?

  • @mhadi-dev
    @mhadi-dev วันที่ผ่านมา +1

    Reply to my comment if you thought this video is about "record uniqueness" when you saw the title.

  • @BsiennKhan
    @BsiennKhan 2 วันที่ผ่านมา +7

    No thanks. Thank you for sharing.

  • @nico_1106
    @nico_1106 วันที่ผ่านมา +2

    What a misinformed advice. It is slow, inefficient and unnecessary 99% of the time. Ever heard of created_at and updated_at?

  • @owenwexler7214
    @owenwexler7214 19 ชั่วโมงที่ผ่านมา

    venue.isHotel 🚫
    venue.becameHotelAt ✅