diff --git a/soitool/database.py b/soitool/database.py
index abb77adf0750021cf28a66ce9c6eeaa7c8ebc8c2..65fb99d72462ec0d55ca690c2eab605b799add19 100644
--- a/soitool/database.py
+++ b/soitool/database.py
@@ -7,7 +7,6 @@ import soitool.coder
 from soitool.enumerates import CodebookSort
 from soitool.serialize_export_import_soi import serialize_soi
 from soitool.compressor import compress
-from soitool.dialog_wrappers import exec_warning_dialog
 
 # Set name and path to default (future) database
 DBNAME = "database"
@@ -20,9 +19,11 @@ SECONDS_IN_24H = 24 * 60 * 60
 # DDL-statements for creating tables
 SOI = (
     "CREATE TABLE SOI("
-    "Title VARCHAR PRIMARY KEY NOT NULL CHECK(length(Title) > 0), "
+    "Title VARCHAR NOT NULL CHECK(length(Title) > 0), "
+    "Version VARCHAR NOT NULL CHECK(length(Version) > 0), "
     "SOI TEXT NOT NULL CHECK(length(SOI) > 0), "
-    "Date DATETIME)"
+    "Date DATETIME, "
+    "PRIMARY KEY(Title, Version))"
 )
 CODEBOOK = (
     "CREATE TABLE Codebook("
@@ -347,44 +348,35 @@ class Database:
             self.conn.execute(stmt, (code, word))
             self.conn.commit()
 
-    def insert_soi(self, soi):
-        """Serialize, compress and insert SOI into database-table SOI.
+    def insert_or_update_soi(self, soi):
+        """Serialize, compress and insert/update SOI in database-table SOI.
 
-        If one or more SOI's with the same title exist in db, '(1)', '(2)', ...
-        is added to the Title-column of the SOI to insert.
+        SOI's with the same title and version are overwritten.
 
         Parameters
         ----------
         soi : soitool.soi.SOI
-            The SOI-instance to insert into database.
+            The SOI-instance to insert or update.
         """
         # Serialize and compress SOI
         compressed_soi = compress(serialize_soi(soi))
 
-        # Count SOI's in database with equal title,
-        # including titles ending with '(x)'
-        title = soi.title
-        length = len(title)
-        stmt = (
-            "SELECT COUNT(*) FROM SOI "
-            "WHERE substr(Title,0,?)=? "
-            "AND (length(Title)=? OR length(Title)=?)"
-        )
-        count = self.conn.execute(
-            stmt, (length + 1, title, length, length + 3)
-        ).fetchone()[0]
-
-        # Add '(x)' to title if one or more SOI's with equal title exist
-        if count > 0:
-            title += "(" + str(count + 1) + ")"
-
-        # Insert SOI into database
-        stmt = "INSERT INTO SOI (Title, SOI, Date) VALUES(?,?,?)"
-        try:
-            self.conn.execute(stmt, (title, compressed_soi, soi.date))
-            self.conn.commit()
-        except sqlite3.IntegrityError:
-            exec_warning_dialog(
-                "SOI ble ikke lagret i databasen.",
-                "Sørg for at SOI'en har en tittel.",
+        # Check if SOI with the same title and version exists
+        stmt = "SELECT COUNT(*) FROM SOI " "WHERE Title=? " "AND Version=?"
+        count = self.conn.execute(stmt, (soi.title, soi.version)).fetchone()[0]
+
+        # If SOI exists, overwrite
+        if count == 1:
+            stmt = "UPDATE SOI SET SOI=?, Date=? WHERE Title=? AND Version=?"
+            self.conn.execute(
+                stmt, (compressed_soi, soi.date, soi.title, soi.version)
             )
+        # SOI does not exist, insert
+        else:
+            stmt = (
+                "INSERT INTO SOI (Title, Version, SOI, Date) VALUES(?,?,?,?)"
+            )
+            self.conn.execute(
+                stmt, (soi.title, soi.version, compressed_soi, soi.date)
+            )
+        self.conn.commit()
diff --git a/soitool/main_window.py b/soitool/main_window.py
index 6992a245d65fe9674ed7a5c2b67aab4998772b0c..a099da8f2186c4e701403a5506e0cf64c1abe3c4 100644
--- a/soitool/main_window.py
+++ b/soitool/main_window.py
@@ -22,8 +22,6 @@ from soitool.codebook_widget import CodebookWidget
 from soitool.codebook_model_view import CodebookTableModel
 from soitool.database import Database, DBPATH
 from soitool.help_actions import ShortcutsHelpDialog, BasicUsageHelpDialog
-from soitool.soi_db_widget import SOIDbWidget
-from soitool.soi_model_view import SOITableModel
 from soitool.serialize_export_import_soi import (
     export_soi,
     import_soi,
@@ -111,7 +109,6 @@ class MainWindow(QMainWindow):
         open_file_db = QAction("Ã…pne fra DB", self)
         open_file_db.setShortcut("Ctrl+d")
         open_file_db.setStatusTip("Ã…pne en SOI fra databasen")
-        open_file_db.triggered.connect(self.show_soi_db)
         file_menu.addAction(open_file_db)
 
         # Preview SOI
@@ -310,24 +307,7 @@ class MainWindow(QMainWindow):
 
         # If tab contains an SOI
         if isinstance(tab_widget, SOIWorkspaceWidget):
-            # Update tab showing SOI's in db if it is open,
-            # and pause database-lock by codebook-tab if it is open.
-            soi_db_view = None
-            codebook_db_view = None
-            for i in range(self.tabs.count()):
-                if self.tabs.tabText(i) == "SOI'er i DB":
-                    soi_db_view = self.tabs.widget(i).view
-                    soi_db_view.setModel(None)
-                elif self.tabs.tabText(i) == "Kodebok":
-                    codebook_db_view = self.tabs.widget(i).view
-                    codebook_db_view.setModel(None)
-
-            self.database.insert_soi(tab_widget.soi)
-
-            if soi_db_view is not None:
-                soi_db_view.setModel(SOITableModel())
-            if codebook_db_view is not None:
-                codebook_db_view.setModel(CodebookTableModel())
+            self.database.insert_or_update_soi(tab_widget.soi)
         else:
             exec_info_dialog(
                 "Valgt tab er ingen SOI-tab",
@@ -335,23 +315,6 @@ class MainWindow(QMainWindow):
                 "Riktig tab må velges for å lagre en SOI i DB.",
             )
 
-    def show_soi_db(self):
-        """Open and select tab containing SOIDbWidget.
-
-        Select tab if it is already open,
-        create and select tab if not open.
-        """
-        # Loop through tabs to look for existing SOI-db-tab:
-        for i in range(self.tabs.count()):
-            if self.tabs.tabText(i) == "SOI'er i DB":
-                self.tabs.setCurrentIndex(i)
-                break
-        # SOI-db-tab does not exist, create, add and select tab
-        else:
-            tab = SOIDbWidget(self.database, self.tabs)
-            self.tabs.addTab(tab, "SOI'er i DB")
-            self.tabs.setCurrentWidget(tab)
-
     def open_shortcut_help(self):
         """Open shortcut dialog."""
         self.popup_shortcut_help.setWindowTitle("Hurtigtaster")
diff --git a/soitool/soi_db_widget.py b/soitool/soi_db_widget.py
deleted file mode 100644
index 343c7d4672c7b7db8557cb59c5836960d2dd317b..0000000000000000000000000000000000000000
--- a/soitool/soi_db_widget.py
+++ /dev/null
@@ -1,19 +0,0 @@
-"""Module containing a widget for viewing and opening SOI's from database."""
-from PySide2.QtWidgets import QWidget, QHBoxLayout
-from soitool.soi_model_view import SOITableView
-
-
-class SOIDbWidget(QWidget):
-    """Widget for viewing and opening SOI's from database."""
-
-    def __init__(self, database, tab_widget):
-        super().__init__()
-
-        self.view = SOITableView(database, tab_widget)
-        self.create_and_set_layout()
-
-    def create_and_set_layout(self):
-        """Create layout, add widget and set layout."""
-        hbox = QHBoxLayout()
-        hbox.addWidget(self.view)
-        self.setLayout(hbox)
diff --git a/soitool/soi_model_view.py b/soitool/soi_model_view.py
deleted file mode 100644
index 3ca3d380fcb36146eada958aa56dcb60ca42a6c0..0000000000000000000000000000000000000000
--- a/soitool/soi_model_view.py
+++ /dev/null
@@ -1,134 +0,0 @@
-"""GUI-interface towards database-table 'SOI'.
-
-Contains functionality for showing and opening SOI's in database.
-"""
-from PySide2.QtWidgets import QTableView
-from PySide2.QtSql import QSqlDatabase, QSqlTableModel
-from PySide2.QtCore import Qt
-from soitool.style import CODEBOOK_HEADER_FONT, CODEBOOK_HEADER_BACKGROUND_CSS
-from soitool.serialize_export_import_soi import construct_soi_from_serialized
-from soitool.soi_workspace_widget import SOIWorkspaceWidget
-
-# Name and type of database
-CONNAME = "SOIDB"
-DBTYPE = "QSQLITE"
-
-
-class SOITableView(QTableView):
-    """TableView with a model of the 'SOI'-table from database.
-
-    This modified QTableView creates a SOITableModel, which reads data from the
-    SOI-table. When the user double-clicks or presses the enter-key, a tab
-    containing SOIWorkspaceWidget, with the SOI from the current row, is opened
-    and selected.
-
-    Parameters
-    ----------
-    database : soitool.database.Database
-        Is used to create a QSqlDatabase from the database-file.
-    tab_widget : QTabWidget
-        Is used to open a new tab.
-
-    Raises
-    ------
-    RuntimeError
-        If database does not open.
-    """
-
-    def __init__(self, database, tab_widget):
-        super().__init__()
-        db = QSqlDatabase.addDatabase(DBTYPE, CONNAME)
-        db.setDatabaseName(database.db_path)
-        self.tab_widget = tab_widget
-
-        if not db.open():
-            raise RuntimeError("Could not open database.")
-
-        # Enable sorting
-        self.setSortingEnabled(True)
-
-        # Create and set model
-        model = SOITableModel()
-        self.setModel(model)
-
-        # Remove horizontal scrollbar, hide vertical header and 'SOI'-column
-        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
-        self.verticalHeader().hide()
-        self.hideColumn(1)
-
-        # Set horizontal header-text and it's style
-        self.set_horizontal_header_text()
-        header = self.horizontalHeader()
-        header.setFont(CODEBOOK_HEADER_FONT)
-        header.setStyleSheet(CODEBOOK_HEADER_BACKGROUND_CSS)
-
-        # Resize
-        self.resizeColumnsToContents()
-        width = self.columnWidth(0) + self.columnWidth(2) + 2  # +2 offset
-        self.setFixedWidth(width)
-
-        self.doubleClicked.connect(self.open_soi_tab)
-
-    def set_horizontal_header_text(self):
-        """Set Norwegian names in horizontal header."""
-        self.model().setHeaderData(0, Qt.Horizontal, "Tittel")
-        self.model().setHeaderData(2, Qt.Horizontal, "Dato")
-
-    def keyPressEvent(self, event):
-        """Open SOI-tab if enter-key is pressed."""
-        if event.key() == Qt.Key_Return:
-            self.open_soi_tab()
-        super().keyPressEvent(event)
-
-    def open_soi_tab(self):
-        """Construct SOI and open SOIWorkspacewidget in new tab."""
-        # Get index of the current row and read compressed, serialized SOI
-        row = self.currentIndex().row()
-        compressed_soi = self.model().index(row, 1).data()
-
-        # Construct SOI and create SOIWorkspaceWidget
-        soi = construct_soi_from_serialized(compressed_soi, compressed=True)
-        tab = SOIWorkspaceWidget(soi)
-
-        # Add and select tab
-        self.tab_widget.addTab(tab, soi.title)
-        self.tab_widget.setCurrentWidget(tab)
-
-    def setModel(self, model):
-        """Set model, resize and hide 'SOI'-column.
-
-        Parameters
-        ----------
-        model : SOITableModel or None
-            Model containing data to display.
-        """
-        super().setModel(model)
-        if model is not None:
-            self.hideColumn(1)
-            self.resizeColumnsToContents()
-            width = self.columnWidth(0) + self.columnWidth(2) + 2  # +2 offset
-            self.setFixedWidth(width)
-
-
-class SOITableModel(QSqlTableModel):
-    """Uneditable QSqlTableModel of database-table 'SOI'."""
-
-    def __init__(self):
-        super().__init__(None, QSqlDatabase.database(CONNAME))
-        self.setEditStrategy(QSqlTableModel.OnFieldChange)
-        self.setTable("SOI")
-        self.setSort(2, Qt.DescendingOrder)  # Sort by date
-        self.select()
-
-    def flags(self, index):
-        """Disable editing.
-
-        Parameters
-        ----------
-        index : QModelIndex
-            Is used to locate data in a model.
-        """
-        flags = super().flags(index)
-        flags ^= Qt.ItemIsEditable
-
-        return flags
diff --git a/test/test_database.py b/test/test_database.py
index ab8b773103e98e2534444e966e1e79f7b4b272dd..42c705285dbe516df3471c488d4032263c366fc1 100644
--- a/test/test_database.py
+++ b/test/test_database.py
@@ -302,7 +302,7 @@ class DatabaseTest(unittest.TestCase):
         test_date = datetime.now().strftime("%Y-%m-%d")
         # Create and insert SOI
         soi = SOI(title=test_title, date=test_date)
-        self.database.insert_soi(soi)
+        self.database.insert_or_update_soi(soi)
 
         # Assert only one SOI is in table
         stmt = "SELECT * FROM SOI"
@@ -311,16 +311,22 @@ class DatabaseTest(unittest.TestCase):
 
         # Assert SOI was written correctly
         self.assertEqual(queried[0]["Title"], test_title)
+        self.assertEqual(queried[0]["Version"], soi.version)
         self.assertEqual(queried[0]["Date"], test_date)
         self.assertEqual(queried[0]["SOI"], compress(serialize_soi(soi)))
 
-        # Insert same SOI again and assert '(2)' is added to title
-        self.database.insert_soi(soi)
-        stmt = "SELECT COUNT(*) FROM SOI WHERE Title=?"
-        count = self.database.conn.execute(
-            stmt, (test_title + "(2)",)
-        ).fetchone()[0]
-        self.assertEqual(count, 1)
+        # Insert the same SOI (same title & version), assert it is overwritten.
+        self.database.insert_or_update_soi(soi)
+        # Assert only one SOI is in table
+        queried = self.database.conn.execute(stmt).fetchall()
+        self.assertEqual(len(queried), 1)
+
+        # Insert another version of the same SOI, assert a new row is added.
+        soi.version = "2"
+        self.database.insert_or_update_soi(soi)
+        # Assert two SOI's are in table
+        queried = self.database.conn.execute(stmt).fetchall()
+        self.assertEqual(len(queried), 2)
 
     def delete_db(self):
         """Delete generated database-file."""