diff --git a/catalogue/SqliteCatalogue.cpp b/catalogue/SqliteCatalogue.cpp
index c2136a4908ccc11394d189650ca944e088e04a45..fecd90d3cbf7eec69fb6304f98a2501b4144b18a 100644
--- a/catalogue/SqliteCatalogue.cpp
+++ b/catalogue/SqliteCatalogue.cpp
@@ -1978,20 +1978,21 @@ bool SqliteCatalogue::hostIsAdmin(const std::string &hostName)
 //------------------------------------------------------------------------------
 // createTapeFile
 //------------------------------------------------------------------------------
-void SqliteCatalogue::createTapeFile(const common::dataStructures::TapeFile &tapeFile,
-  const uint64_t archiveFileId) {
+void SqliteCatalogue::createTapeFile(const common::dataStructures::TapeFile &tapeFile, const uint64_t archiveFileId) {
   const time_t now = time(NULL);
   const char *const sql =
     "INSERT INTO TAPE_FILE("
       "VID,"
       "FSEQ,"
       "BLOCK_ID,"
+      "COPY_NB,"
       "CREATION_TIME,"
       "ARCHIVE_FILE_ID)"
     "VALUES("
       ":VID,"
       ":FSEQ,"
       ":BLOCK_ID,"
+      ":COPY_NB,"
       ":CREATION_TIME,"
       ":ARCHIVE_FILE_ID);";
   std::unique_ptr<SqliteStmt> stmt(m_conn.createStmt(sql));
@@ -1999,6 +2000,7 @@ void SqliteCatalogue::createTapeFile(const common::dataStructures::TapeFile &tap
   stmt->bind(":VID", tapeFile.vid);
   stmt->bind(":FSEQ", tapeFile.fSeq);
   stmt->bind(":BLOCK_ID", tapeFile.blockId);
+  stmt->bind(":COPY_NB", tapeFile.copyNb);
   stmt->bind(":CREATION_TIME", now);
   stmt->bind(":ARCHIVE_FILE_ID", archiveFileId);
 
@@ -2015,6 +2017,7 @@ std::list<common::dataStructures::TapeFile> SqliteCatalogue::getTapeFiles() cons
       "VID           AS VID,"
       "FSEQ          AS FSEQ,"
       "BLOCK_ID      AS BLOCK_ID,"
+      "COPY_NB       AS COPY_NB,"
       "CREATION_TIME AS CREATION_TIME "
     "FROM TAPE_FILE;";
   std::unique_ptr<SqliteStmt> stmt(m_conn.createStmt(sql));
@@ -2028,6 +2031,7 @@ std::list<common::dataStructures::TapeFile> SqliteCatalogue::getTapeFiles() cons
     file.vid = stmt->columnText(nameToIdx["VID"]);
     file.fSeq = stmt->columnUint64(nameToIdx["FSEQ"]);
     file.blockId = stmt->columnUint64(nameToIdx["BLOCK_ID"]);
+    file.copyNb = stmt->columnUint64(nameToIdx["COPY_NB"]);
     file.creationTime = stmt->columnUint64(nameToIdx["CREATION_TIME"]);
 
     files.push_back(file);
diff --git a/catalogue/SqliteCatalogueTest.cpp b/catalogue/SqliteCatalogueTest.cpp
index e13c8a0789db30868b9266e8524cbb9fd8a785dd..d1c5033173c2e2a18de6a4b1f31083739ee08835 100644
--- a/catalogue/SqliteCatalogueTest.cpp
+++ b/catalogue/SqliteCatalogueTest.cpp
@@ -1062,6 +1062,7 @@ TEST_F(cta_catalogue_SqliteCatalogueTest, createTapeFile) {
 
   common::dataStructures::TapeFile tapeFile;
   tapeFile.vid = "VID";
+  tapeFile.copyNb = 1;
   tapeFile.fSeq = 5678;
   tapeFile.blockId = 9012;
 
@@ -1073,6 +1074,7 @@ TEST_F(cta_catalogue_SqliteCatalogueTest, createTapeFile) {
 
   ASSERT_EQ(1, tapeFiles.size());
   ASSERT_EQ(tapeFile.vid, tapeFiles.front().vid);
+  ASSERT_EQ(tapeFile.copyNb, tapeFiles.front().copyNb);
   ASSERT_EQ(tapeFile.fSeq, tapeFiles.front().fSeq);
   ASSERT_EQ(tapeFile.blockId, tapeFiles.front().blockId);
 }
diff --git a/catalogue/catalogue_schema.pdf b/catalogue/catalogue_schema.pdf
index 730b8a4bb00399954b29d64f04b573901105c834..f1d43200dc4f4e76ec67af8c171c30ba148e4ef3 100644
Binary files a/catalogue/catalogue_schema.pdf and b/catalogue/catalogue_schema.pdf differ
diff --git a/catalogue/catalogue_schema.sql b/catalogue/catalogue_schema.sql
index f9f1b430b158ef840f293684050984657ed5a9b5..4fb4cc6be26642761daa156194b09105a20057bb 100644
--- a/catalogue/catalogue_schema.sql
+++ b/catalogue/catalogue_schema.sql
@@ -190,10 +190,12 @@ CREATE TABLE TAPE_FILE(
   VID             VARCHAR2(100) NOT NULL,
   FSEQ            INTEGER       NOT NULL,
   BLOCK_ID        INTEGER       NOT NULL,
+  COPY_NB         INTEGER       NOT NULL,
   CREATION_TIME   INTEGER       NOT NULL,
   ARCHIVE_FILE_ID INTEGER       NOT NULL,
   CONSTRAINT TAPE_FILE_PK PRIMARY KEY(VID, FSEQ),
   CONSTRAINT TAPE_FILE_ARCHIVE_FILE_FK FOREIGN KEY(ARCHIVE_FILE_ID)
     REFERENCES ARCHIVE_FILE(ARCHIVE_FILE_ID),
-  CONSTRAINT TAPE_FILE_FSEQ_BLOCK_ID_UN UNIQUE(FSEQ, BLOCK_ID)
+  CONSTRAINT TAPE_FILE_VID_BLOCK_ID_UN UNIQUE(VID, BLOCK_ID),
+  CONSTRAINT TAPE_FILE_VID_COPY_NB_UN UNIQUE(VID, COPY_NB)
 );
diff --git a/common/dataStructures/TapeFile.hpp b/common/dataStructures/TapeFile.hpp
index 4f82d8c89cfa405d8518e284466fc3af7cf05551..6ea137c6723d21f8c8ffc478f251f3b57b9c21c3 100644
--- a/common/dataStructures/TapeFile.hpp
+++ b/common/dataStructures/TapeFile.hpp
@@ -39,9 +39,29 @@ struct TapeFile {
 
   bool operator!=(const TapeFile &rhs) const;
 
+  /**
+   * The volume indentifier of the tape on which the file has been written.
+   */
   std::string vid;
+
+  /**
+   * The copy number of the file.  Copy numbers start from 1.
+   */
+  uint64_t copyNb;
+
+  /**
+   * The position of the file on tape in the form of its file sequence number.
+   */
   uint64_t fSeq;
+
+  /**
+   * The position of the file on tape in the form of its logical block identifier.
+   */
   uint64_t blockId;
+
+  /**
+   * The time the file recorded in the catalogue.
+   */
   time_t creationTime;
 
 }; // struct TapeFile