1. 22

  2. 5

    Almost nothing in my career has made me think “there has to be another way” more often than having to rename a column or table. It’s hard to get names right the first time, and there is value in keeping names relevant.

    Renaming safely and without downtime involves a whole dance around making a new thing, copying over the old stuff, double-writing, etc. At scale you run into organizational checks and balances, and it ends up taking weeks.

    In particular, I’ve long wondered why databases didn’t have an “alias” feature that let you give a table or column more than one name. It seems like it’d be a negligible cost to have the query parser or planner to check alias mappings. This would make name migration a lot less painful. You could also imagine affordances to limit the scope and complexity, like letting you atomic-swap the true name with an alias, or only allowing one alias, etc.

    What would be the practical or philosophical downsides to something like this? Harder to implement than I assume? Introduces footguns? Duplicative of some other feature? Details too bikesheddy?

    1. 6

      The CREATE VIEW from the article is essentially an alias, since it lets you write UPDATE old_name and still work.

      1. 2

        Yep, and it looks like MySQL has a similar facility. Both implementations come with asterisks that I’m not sure I’d care about in practice, so I’d be happy to use this to make my life easier!

        I do still wonder about an asterisk-free scenario where names of tables/columns are mapped many-to-one to an underlying object, e.g., as Unix file links are to inodes.

    2. 2

      Good article.

      That said, I’m a little (but only a little) surprised that I don’t see folks talking about feature / version detection, sort of like feature flags for your schema. So you’d end up with a repository where at the start of a transaction, you’d lookup the current version, and switch your implementation based on that. So assuming you can run transations at snapshot isolation or better, the worst case is that you end up failing a write when the table name change concurrentlly, and then retry.

      Granted, it’s a bit of a faff, but it’s no more onerous than what I’d have to do at work for something similar.

      1. 2

        Is there a way in SQL to parameterize a table name? Seems like you’d have to do one transaction to detect versions and a second to do the real transaction, which is racey.

        1. 2

          … and a second to do the real transaction, which is racey

          Yeah, it would be. As an example of what I’m thinking, you’d have a pseudo-SQL transcript something like this:

          -- Check if the migration has run
          SELECT name FROM migrations WHERE name = 'rename-foo-to-foo-v2';
          -- If there was no row returned, then we do:
            SELECT stuff FROM foo;
            -- else:
            SELECT other_stuff FROM foo_v2;
          -- end if.

          So it’s all done within the one transaction.

          1. 3

            As someone who has written a lot of Cadence workflows, where this is the norm, and suffered the maintenance burden of the dead code, I know exactly why—it’s a lot of work.

            Approaches like the article are very silver bullety, and everyone gets on board with that, first.

            1. 1

              Yeah, I guess there’s the same issue as with regular feature flags (or even just regular expand / migrate / contract migrations). If you’re not on top of cleaning up old ones, then they’ll just hang around, adding complication. I’d like to imagine that both paths wouldn’t co-exist for a deploy or two in most circumstances, though.

      2. 1

        I like that the article is short and to the point.