Leighton, think of it this way:
The Extract that Tableau creates is a static representation of the state of the data at the time the extract was created. Tableau then uses this brand new data model in the workbook(s) you create - the original state of the data (in your case, in a relational database of some kind) is completely unknown to Tableau. The only thing Tableau knows about is the new, static data model.
So, if you change that static data model (the extract), then Tableau has to create a NEW static data model that incorporates your changes. That's why you get prompted to save a new extract after you do a join inside Tableau.
That's a simplification of what's going on but it will do to illustrate what you're seeing.
Does that make sense?
Thanks Michael. I had originally thought the Extract was more akin to a local copy of the tables/relational databases. This has cleared up my confusion.
Glad that helped.
A little more technical detail:
Whenever Tableau opens a data source that you have defined, it creates an in-memory representation of that data source in an optimized format. Tableau then performs all actions against that in-memory data model, which can look very different from the original source data model. It is highly optimized for Tableau's needs.
An extract action causes Tableau to write that in-memory model to an external file: .tde or .hyper, depending on the version of Tableau you're using. That makes it portable, and allows you to publish that extract to Server so that Server can manage the data refresh process for you.